我听说printf比echo. 根据我的经验,我只能回忆起一个我不得不使用的实例,printf因为它echo无法将一些文本输入到 RHEL 5.8 上的某个程序中,但printf确实如此。但显然,还有其他差异,我想询问它们是什么以及是否有特定情况下何时使用一种与另一种。
我一直看到引用此链接的答案明确指出“不要解析ls!” 这让我感到困扰有几个原因:
似乎该链接中的信息已被批量接受,几乎没有问题,尽管我可以在随意阅读中至少挑出一些错误。
该链接中所述的问题似乎也引发了不想找到解决方案的愿望。
从第一段:
...当你要求
[ls]一个文件列表时,有一个大问题:Unix 允许文件名中的几乎任何字符,包括空格、换行符、逗号、管道符号,以及几乎任何你曾经尝试用作除 NUL 外的分隔符。...ls用换行符分隔文件名。这很好,直到您的文件名称中包含换行符。并且由于我不知道任何ls允许您使用 NUL 字符而不是换行符终止文件名的实现,这使我们无法使用ls.
无赖,对吧?如何以往我们可以处理一个换行符终止的上市数据集可能包含换行符的数据?好吧,如果这个网站上回答问题的人不是每天都做这种事情,我可能会认为我们遇到了麻烦。
事实是,大多数ls实现实际上提供了一个非常简单的 api 来解析它们的输出,我们一直在做,甚至没有意识到。您不仅可以以 null 结束文件名,还可以以 null 或您可能需要的任何其他任意字符串开头。更重要的是,您可以为每个文件类型分配这些任意字符串。请考虑:
LS_COLORS='lc=\0:rc=:ec=\0\0\0:fi=:di=:' ls -l --color=always | cat -A
total 4$
drwxr-xr-x 1 mikeserv mikeserv 0 Jul 10 01:05 ^@^@^@^@dir^@^@^@/$
-rw-r--r-- 1 mikeserv mikeserv 4 Jul 10 02:18 ^@file1^@^@^@$
-rw-r--r-- 1 mikeserv mikeserv 0 Jul 10 01:08 ^@file2^@^@^@$
-rw-r--r-- 1 mikeserv mikeserv 0 Jul …Run Code Online (Sandbox Code Playgroud) 在运行脚本时,我想在/tmp目录中创建一个临时文件。
执行该脚本后,该脚本将清除该脚本。
如何在shell脚本中做到这一点?
过去的旧建议是对任何涉及 a 的表达式加双引号$VARIABLE,至少在希望 shell 将其解释为单个项目的情况下,否则,内容中的任何空格$VARIABLE都会脱离 shell。
但是,我知道在较新版本的 shell 中,不再总是需要双引号(至少出于上述目的)。例如,在bash:
% FOO='bar baz'
% [ $FOO = 'bar baz' ] && echo OK
bash: [: too many arguments
% [[ $FOO = 'bar baz' ]] && echo OK
OK
% touch 'bar baz'
% ls $FOO
ls: cannot access bar: No such file or directory
ls: cannot access baz: No such file or directory
Run Code Online (Sandbox Code Playgroud)
在zsh,而另一方面,同样的三个命令成功。因此,基于此实验,似乎在 中bash可以省略 内部的双引号[[ ... ]],但不能省略内部 …
我注意到它|用于将第一个命令的结果发送给另一个。我想杀死所有与名称匹配的进程。
这是 pgrep 通常所做的:
$ pgrep name
5089
5105
Run Code Online (Sandbox Code Playgroud)
并且多个参数似乎适用于kill:
sudo kill 5089 5105
Run Code Online (Sandbox Code Playgroud)
但这是错误的:
pgrep name | kill
Run Code Online (Sandbox Code Playgroud)
那么如何正确操作呢?
我希望能够捕获命令替换的确切输出,包括尾随的换行符。
我意识到默认情况下它们会被剥离,因此可能需要进行一些操作才能保留它们,并且我想保留原始退出代码。
例如,给定一个带有可变数量的尾随换行符和退出代码的命令:
f(){ for i in $(seq "$((RANDOM % 3))"); do echo; done; return $((RANDOM % 256));}
export -f f
Run Code Online (Sandbox Code Playgroud)
我想运行类似的东西:
exact_output f
Run Code Online (Sandbox Code Playgroud)
并有输出:
Output: $'\n\n'
Exit: 5
Run Code Online (Sandbox Code Playgroud)
我对bashPOSIX 和 POSIX都感兴趣sh。
如何将标准输出发送到控制台并同时通过管道发送到下一个命令?
我已经尝试使用此处建议的 Read 命令,该命令可以将 Grep 的输出从日志文件的尾部获取到变量,然后获取到日志或电子邮件,但我仍然希望将输出获取到标准输出控制台还有: https://unix.stackexchange.com/a/365222/346155
我尝试过使用 Tee,如下所示: https: //unix.stackexchange.com/a/47936/346155
我使用 --line-buffered 标志以防万一: /sf/answers/501402891/
我可能遗漏了一些关于 sdtin 逻辑的简单内容,但第一个链接的情况表明 Bash 可能不具备这种简单的功能。并且该变量无法从子 shell 中读取。
有效的事实echo 'hello' | echo $(</dev/stdin)表明它是可能的。另一种看待它的方法是,如何在每个管道段内进行标准输出到控制台。这应该有助于在将一长串命令提交到 bash 脚本之前对其进行调试。
编辑:类似echo 'hello' | echo $(</dev/stdin) >/dev/stoutor 的东西echo 'hello' | tee >/dev/stdout | echo 2nd $(</dev/stdin),后者应该输出 'hello' 两次,但只输出一次。