代写一个类似Shell功能的命令行工具,第三部分是I/O的重定向,包括管道操作,也就是<
,>
和|
这三个符号。
Part III: Output Redirection
One of the most powerful features of a Unix-like shell is the ability to compose a series of simple applications to create a complex workflow. The key feature that enables this composition is output redirection.
Redirection is accomplished by three special characters <
, >
, and |
. You will need to add logic to your parsing code that identifies these characters and uses them to identify shell-level directives, rather than simply passing them to exec.
The first two characters, <
and >
, can direct input from a file into a program and output from a program respectively.
sfish > ls - l > newfile
sfish > grep .c < newfile
# Output from ls -l
sfish > echo "Hello, World!" > file
sfish > cat file
Hello, World!
sfish>
In the example above, the standard output of ls -l
is redirected to a file named newfile. If newfile didn’t exist before the command was executed, the shell created it. If newfile did exist before the command was executed, the shell overwrote it.
The example above also shows the input redirection of grep
using <
. The standard input of grep
is set to the file newfile rather than input from the terminal.
The
ls
program does not know it is writing to a file and is not passed the string> newfile
as an argument. Instead, the shell redirects stdout ofls
to the file. Similarly, in the second command, the contents of newfile are passed to thegrep
program as its standard input ( stdin ).
You are not constrained to using just standard input (handle 0) and standard output (handle 1) with these operators. You should be able to put 2 in front of the >
operator to redirect output of stderr to a file.
sfish > somecommand 2>err.log
# This example runs "somecommand" and redirects its stderr to "err.log".
In the example above, the output from stderr is redirected to the file err.log . Only the output from stderr is written to this file. If >
is used without a handle, then it redirects output from stdout only.
sfish >./hw1 < in.txt > out.txt
In the example above both the input and output of ./hw1 are being redirected. hw1’s input will be taken from the file in.txt and it’s output will be written to the file out.txt .
You’ll have to learn how to manipulate file descriptors carefully using system calls such as open, close, read, write, dup/dup2, and more.
Finally, you can redirect output from one application to another using the pipe |
operator:
sfish > ls | grep '.txt' | wc -l
4
In this example, the shell creates three child processes. The first, ls
, reads the contents of the home directory, which gets redirected to the grep
program. grep
searches for all instances of the string ‘.txt’ in it’s input (the output of ls
). The output of grep
, i.e., all files with the .txt
extension, is then sent to the wc program. wc counts how many lines of input it is given. (the number of .txt
files in the home directory)
The following features must be implemented:
- Add support for all three forms of redirection described above, > , < , and | .
- Be sure to run several test cases for piping applications together and multiple redirection. Ensure that termination is handled cleanly.
- Examples:
- hw1 < in.txt > out.txt
- ls | grep ‘.txt’ | wc -l
Look at the man pages for grep, sort, wc, head, tail, etc. for parameters and flags.