对于命令(内置或外部),直接在 bash shell 进程中运行它和bash -c在 bash shell中运行它有什么区别?与彼此相比,它们的优点和缺点是什么?
For example, in a bash shell, run `date` directly, and run `bash -c
date`. Also consider a builtin command instead of an external one.
Run Code Online (Sandbox Code Playgroud)
G-M*_*ca' 13
该-c选项允许程序运行命令。分叉和做要容易得多
execl("/bin/sh", "sh", "-c", "date | od -cb && ps > ps.out", NULL);
Run Code Online (Sandbox Code Playgroud)
比分叉,创建管道,再次分叉,调用execl每个孩子,调用wait,检查退出状态,再次分叉,调用close(1),打开文件,确保它在文件描述符上打开?1,然后再做一次execl。我相信这就是最初创建该选项的原因。
的system()库函数运行通过上述方法的指令。
find … -exec或 )的程序很有用xargs。但你已经知道了;这是您问题的答案的一部分,
如何将复合命令指定为另一个命令的参数?如果您运行的是 bash 以外的交互式 shell,它会派上用场。相反,如果您正在运行 bash,则可以使用此语法
$ ash -c "命令"
?
$ csh -c "命令"
?
$ dash -c "命令"
?
$ zsh -c "命令"
?
在另一个 shell 中运行一个命令,因为所有这些 shell 也识别该-c选项。当然,您可以使用
$灰
ash$命令
?
ash$ 退出
$ csh
csh$命令
?
csh$ 退出
$破折号
破折号$命令
?
破折号$退出
$ zsh
zsh$命令
?
zsh$ 退出
我用ash$ , etc. 来说明来自不同 shell 的提示;你可能不会真正得到那些。
如果您想在“新鲜”的 bash shell 中运行一个命令,它会派上用场;例如,
$ ash -c "command"
?
$ csh -c "command"
?
$ dash -c "command"
?
$ zsh -c "command"
?
或者
$ ash
ash$ command
?
ash$ exit
$ csh
csh$ command
?
csh$ exit
$ dash
dash$ command
?
dash$ exit
$ zsh
zsh$ command
?
zsh$ exit以上是一种误导性的过度简化。当 bash 与 一起运行时-c,它被认为是一个非交互式shell ~/.bashrc,除非-i指定,否则它不会读取。所以,
$输入cp
cp 别名为 'cp -i' # 在~/.bashrc 中定义
$ cp .file1 文件2
cp:覆盖'file2'?n
$ bash -c "cp .file1 file2"
# 现有文件未经确认即被覆盖!
$ bash -c -i "cp .file1 file2"
cp:覆盖'file2'?n
您可以使用-ci,-i -c或-ic代替-c -i。
这可能在某种程度上适用于第 3 段中提到的其他 shell,因此长格式(即第二种格式,实际上与键入的数量完全相同)可能更安全,尤其是如果您设置了初始化/配置文件?为那些贝壳做准备。
正如通配符解释的那样,由于您正在运行一个新的进程树(一个新的 shell 进程,可能还有它的子进程),在子 shell 中对环境所做的更改
不会影响父 shell(当前目录、环境值)变量、函数定义等)因此,很难想象一个 shell 内置命令在由sh?-c.?
fg, bg,jobs不能影响或访问由父 shell 启动的后台作业,也不能wait等待它们。
本质上等同于直接从交互式 shell 以正常方式运行。
浪费时间。
和sh?-c "exec some_program"some_programsh?-c exitulimitumask 可以更改子进程的系统设置,然后退出而不执行它们。
几乎唯一可以在sh?-c上下文中起作用的内置命令是kill. 当然,只产生输出的命令(echo、printf、pwd和type)不受影响,而且,如果你写一个文件,它会一直存在。
sh?-c "cd some_directory ; some_program "但是您可以使用普通子外壳实现基本相同的效果:
(cd some_directory ; some_program )这是更有效的。可以说相同的(两个部分)类似的东西
sh?-c "umask 77; some_program "或
ulimit(或shopt)。并且由于您可以将任意复杂的命令放在后面-c- 直到一个成熟的 shell 脚本的复杂性 - 您可能有机会使用任何内置命令;例如source,read,export,times,set和unset等。运行bash -c "my command here"与仅运行my command here的主要区别在于,前者启动子shell,后者运行当前shell 中的命令。
至于内置命令与外部命令,它并没有真正相关——任何你可以在当前 shell 中运行的东西,你都可以在子 shell 中运行。
但是,效果存在许多差异:
这远不是一个详尽的差异列表,但它包含了关键点:您正在运行一个不同的进程bash -c;它与原始 shell 的过程不同。
生成子shell也会导致性能下降;如果您的脚本经常运行,或者您的命令在某种循环中,这将是最相关的。