12
5
This site had a lot of problems involving implementing various languages in interpreter tag. However, practically all of them were esoteric languages that nobody uses. Time to make an interpreter for a practical language that most of users here probably already know. Yes, it's shell script, in case you have problems reading the title (not that you have). (yes, I intentionally made this challenge, as I'm bored of languages like GolfScript and Befunge winning everything, so I put some challenge where more practical programming language have bigger chances of winning)
However, the shell script is a relatively big language, so I won't ask you to implement it. Instead, I'm going to make a small subset of shell script functionality.
The subset I decided on is the following subset:
- Executing programs (programs will only contain letters, however, even if single quotes are allowed)
- Program arguments
- Single quotes (accepting any printable ASCII character, including whitespace, excluding single quote)
- Unquoted strings (allowing ASCII letters, numbers, and dashes)
- Pipes
- Empty statements
- Multiple statements separated by new line
- Trailing/leading/multiple spaces
In this task, you have to read the input from STDIN, and run every requested command. You can safely assume POSIX-compatible operating system, so there is no need for portability with Windows, or anything like that. You can safely assume that the programs that aren't piped to other programs won't read from STDIN. You can safely assume that the commands will exist. You can safely assume that nothing else will be used. If some safe assumption is broken, you can do anything. You can safely assume at most 15 arguments, and lines below 512 characters (if you need explicit memory allocation, or something - I'm really going to give small chances of winning for C, even if they are still small). You don't have to clean up file descriptors.
You are allowed to execute programs at any point - even after receiving the full line, or after STDIN ends. Choose any approach you want.
Simple testcase that lets you test your shell (note the trailling whitespace after third command):
echo hello world
printf '%08X\n' 1234567890
'echo' 'Hello, world!'
echo heeeeeeelllo | sed 's/\(.\)\1\+/\1/g'
yes|head -3
echo '\\'
echo 'foo bar baz' | sed 's/bar/BAR/' | sed 's/baz/zap/'
The program above should output following result:
hello world
499602D2
Hello, world!
helo
y
y
y
\\
foo BAR zap
You aren't allowed to execute the shell itself, unless you don't have any arguments for the command (this exception was made for Perl, which runs command in shell when put just argument in system
, but feel free to abuse this exception for other languages too, if you can do that in a way that saves characters), or the command you run is shell itself. This is probably the biggest problem in this challenge, as many languages have system
functions that execute shell. Instead use language APIs that call programs directly, like subprocess
module in Python. This is a good idea for security anyway, and well, you wouldn't want to create an insecure shell, would you want to? This most likely stops PHP, but there are other languages to choose anyway.
If you are going to make your program in shell script, you aren't allowed to use eval
, source
, or .
(as in, a function, not a character). It would make the challenge too easy in my opinion.
Clever rule abuse allowed. There are lots of things I explicitly disallowed, but I'm almost sure that you are still allowed to do things I haven't though of. Sometimes I'm surprised about how people interpret my rules. Also, remember that you can do anything for anything I haven't mentioned. For example, if I try to use variables, you can wipe the hard disk (but please don't).
The shortest code wins, as this is codegolf.
Pipes... Why'd it have to be pipes... – J B – 2014-01-04T11:00:47.820
1@JB: Shell script without pipelines is not shell script in my opinion, as the code flow in UNIX shell is based on pipes. – Konrad Borowski – 2014-01-04T11:03:57.953
I agree. I still think it's hands down the most painful part of the challenge to implement. – J B – 2014-01-04T11:05:12.223
@JB I agree; I'm skipping this one. – Timtech – 2014-01-04T12:34:23.423
@Timtech: Just mentioning - feel free to skip the parts of challenge, but don't except me to upvote or accept the answer :). – Konrad Borowski – 2014-01-04T12:36:45.347
4I meant that I'm skipping the challenge altogether. – Timtech – 2014-01-04T12:47:48.463
Since you want to give C a chance, how clean does it have to be? Does it have to close file descriptors and reap children, or can we leave these resources lying around till termination? – MvG – 2014-01-05T21:28:30.213
@MvG: No, it doesn't have to clean up. You can safely assume you won't run from file descriptors. – Konrad Borowski – 2014-01-06T08:15:56.053