- Linux Shell Scripting Cookbook(Third Edition)
- Clif Flynt Sarath Lakshman Shantanu Tushar
- 272字
- 2021-07-09 19:46:16
While and subshell trick with stdin
The xargs command places arguments at the end of a command; thus, xargs cannot supply arguments to multiple sets of commands. We can create a subshell to handle complex situations. The subshell can use a while loop to read arguments and execute commands in a trickier way, like this:
$ cat files.txt | ( while read arg; do cat $arg; done ) # Equivalent to cat files.txt | xargs -I {} cat {}
Here, by replacing cat $arg with any number of commands using a while loop, we can perform many command actions with the same arguments. We can pass the output to other commands without using pipes. Subshell ( ) tricks can be used in a variety of problematic environments. When enclosed within subshell operators, it acts as a single unit with multiple commands inside, like so:
$ cmd0 | ( cmd1;cmd2;cmd3) | cmd4
If cmd1 is cd / within the subshell, the path of the working directory changes. However, this change resides inside the subshell only. The cmd4 command will not see the directory change.
The shell accepts a -c option to invoke a subshell with a command-line script. This can be combined with xargs to solve the problem of needing multiple substitutions. The following example finds all C files and echoes the name of each file, preceded by a newline (the -e option enables backslash substitutions). Immediately after the filename is a list of all the times main appears in that file:
find . -name '*.c' | xargs -I ^ sh -c "echo -ne '\n ^: '; grep main ^"