Home

Search IconIcon to open search

minishell

A School 21 project. Write your own shell.

You should watch intranet tutorials! Though I couldn’t find them…

# Lexer and parser

I want to implement a Recursive descent parser. UPD: I gave up the bonus part. Recursive descent parser is an overkill for the mandatory part, but whatever.

# Clean-up

Should I call rl_clear_history? There are no leaks, even if I don’t call it.

# Exiting shell

# Notes on Bash behavior

It doesn’t matter where exactly you put redirects (>, >>):

1
2
3
echo foo bar baz > out # writes "foo bar baz" to file "out"
echo foo bar > out baz # does the same
> out echo foo bar baz # does the same

If the output is both redirected to a file and piped to the next command, it won’t be piped, only written to a file.

1
2
echo foo > bar | tee # doesn't pring anything, writes to "bar"
echo foo > bar | echo baz > wat # writes to files "bar" and "wat"

| (pipe) has higher priority than &&/||.

Backslash \ escapes one special char (space, &, |, maybe others).

Seems like we don’t have to implement command substitution ($(...)), only environment variables (like $PWD).

&& and || have equal precedence and are executed left to right. Use () to change priority. UPD: () actually creates a subshell. So stuff like this is valid:

1
echo foo | (tee | cat)

According to the checklist, “() should behave like in Bash”. Goodbye bonus part, then.

Some examples of how Bash does stuff:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$ tee << eof
> $PWD
> '$PWD'
> "$PWD"
> eof
/home/psharen/42/minishell/experiments
'/home/psharen/42/minishell/experiments'
"/home/psharen/42/minishell/experiments"

$ rm foo\  bar # delete the files named 'foo ' (with a space) and 'bar'

# If there's no space between a quoted string and a command,
# they're the same word.
$ e"cho" hello
hello

$ echo "foo"bar
foobar

$ echo "hel""lo"
hello

$ echo foo > bar > baz # writes "foo" to "baz", creates empty file "bar"
# if we would remove write access to "bar", it would give us error and
# won't execute further. The logic is - create/open all needed files
# first, then write to the last one.

$ "" echo hello # nothing happens, not even an error

$ > wat # creates empty file "wat"

Links

# Non-tty mode

Minishell should work not only as an interactive shell, but as an interpreter too (if I understood the subject right):

1
2
$ echo "echo foo bar" | ./minishell
foo bar

# Examples

# Readline