Stu*_*ent 4 shell pipe io-redirection
shell 管道的威力如此之大,有时让我失望。
只是作为一个例子,管道
echo abc > file.txt
cat file.txt | sed 's/a/1/' > file.txt
Run Code Online (Sandbox Code Playgroud)
给我一个空的file.txt
。意识到 shell 可能>
首先调用,我做了一个改变:
echo abc > file.txt
{cat file.txt | sed 's/a/1/'} > file.txt
Run Code Online (Sandbox Code Playgroud)
另一个空文件再次让我感到惊讶file.txt
。一种最终有效的丑陋方式是
echo abc > file.txt
echo $(cat file.txt | sed 's/a/1') > file.txt
Run Code Online (Sandbox Code Playgroud)
这会强制 shell 首先运行子 shell,然后重定向。
虽然我知道更好的实践sed
,它可以让你摆脱echo
, cat
, grep
.. 等,但我在这里很好奇的是完全学习 shell 的语法。这个问题不是关于如何解决上面的特定问题。
Q1(编辑:题外话)有没有好的资源可以让我学习语法?
恐怕不同的外壳可能有不同的语法,所以
Q2我可以使 shell 变得冗长,并且每次运行命令时都能清楚地看到它在做什么吗?
Q3(编辑:题外话)关于良好实践的任何其他建议?谢谢!
gle*_*man 12
考虑3.1.1 Shell Operation,特别是做事情的顺序:
这意味着 for cat file > file
,输出重定向(截断文件)在cat
产生之前发生,cat
现在有一个空文件可以使用。
但是会echo "$(cat file)" > file
执行您期望的操作,因为命令替换是Shell Expansion,并且发生在重定向之前。
典型的建议是做
cat file > tmpfile && mv tmpfile file
Run Code Online (Sandbox Code Playgroud)
你可以mktemp
在这里使用。
或者安装moreutils
包并使用sponge
cat file | sponge file
Run Code Online (Sandbox Code Playgroud)
尽管要解决您正在使用的特定命令,请替换
cat file.txt | sed 's/a/1/' > file.txt
Run Code Online (Sandbox Code Playgroud)
与(假设 GNU sed)
sed -i 's/a/1/' file.txt
Run Code Online (Sandbox Code Playgroud)
您已经成功找到了您不应该做的事情之一 :-) 永远不要重定向到您正在处理的文件!
A1:学习 shell 语法的好资源是绝对的 bash 脚本指南,IMO
A2:对于 bash 脚本,您可以使用set +x
更详细的输出,但我不知道如何在“在提示符下运行”级别实现相同的输出。
A3:添加[solved]
到您的搜索词。为您找到问题的解决方案,而不是更多您已经知道的问题。
归档时间: |
|
查看次数: |
2197 次 |
最近记录: |