如何在当前shell中执行命令的输出?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在当前shell中执行命令的输出?相关的知识,希望对你有一定的参考价值。
我很清楚source
(又名.
)实用程序,它将从文件中获取内容并在当前shell中执行它们。
现在,我正在将一些文本转换为shell命令,然后运行它们,如下所示:
$ ls | sed ... | sh
ls
只是一个随机的例子,原始文本可以是任何东西。 sed
也是一个转换文本的例子。有趣的是sh
。我把所有的东西都送到了sh
并运行它。
我的问题是,这意味着启动一个新的子shell。我宁愿让命令在我当前的shell中运行。就像我可以用source some-file
一样,如果我在文本文件中有命令。
我不想创建临时文件因为感觉很脏。
或者,我想以与当前shell完全相同的特性启动我的子shell。
update
好吧,使用反引号的解决方案当然有效,但我经常需要在检查和更改输出时这样做,所以我更喜欢是否有办法将结果输入到最后。
sad update
啊,/dev/stdin
的东西看起来很漂亮,但是,在一个更复杂的情况下,它没有用。
所以,我有这个:
find . -type f -iname '*.doc' | ack -v '.doc$' | perl -pe 's/^((.*).doc)$/git mv -f $1 $2.doc/i' | source /dev/stdin
这确保所有.doc
文件的扩展名都是小写的。
顺便说一句,可以用xargs
来处理,但这是重点。
find . -type f -iname '*.doc' | ack -v '.doc$' | perl -pe 's/^((.*).doc)$/$1 $2.doc/i' | xargs -L1 git mv
所以,当我运行前者时,它会马上退出,没有任何反应。
$ ls | sed ... | source /dev/stdin
更新:这适用于bash 4.0,以及tcsh和dash(如果你将source
更改为.
)。显然这是bash 3.2中的错误。来自bash 4.0 release notes:
修复了导致“。”的错误。无法从非常规文件(如设备或命名管道)读取和执行命令。
eval
命令就是出于这个目的而存在的。
eval "$( ls | sed... )"
更多来自bash manual:
EVAL
eval [arguments]
参数连接在一起形成一个命令,然后读取并执行该命令,并将其退出状态作为eval的退出状态返回。如果没有参数或只有空参数,则返回状态为零。
哇,我知道这是一个老问题,但我最近发现自己有同样的问题(这就是我到这里的方式)。
无论如何 - 我不喜欢source /dev/stdin
的答案,但我认为我发现了一个更好的答案。实际上看起来很简单:
echo ls -la | xargs xargs
很好,对吧?实际上,这仍然没有做你想要的,因为如果你有多行,它会将它们连接成一个命令而不是分别运行每个命令。所以我找到的解决方案是:
ls | ... | xargs -L 1 xargs
-L 1
选项意味着每个命令执行使用(最多)1行。注意:如果您的行以尾随空格结尾,它将与下一行连接!因此,请确保每一行以非空格结束。
最后,你可以做到
ls | ... | xargs -L 1 xargs -t
查看执行的命令(-t是详细的)。
希望有人读到这个!
尝试使用process substitution,它将命令的输出替换为临时文件,然后可以获取该文件:
source <(echo id)
我相信这是问题的“正确答案”:
ls | sed ... | while read line; do $line; done
也就是说,人们可以进入while
循环; read
命令命令从其stdin
获取一行并将其分配给变量$line
。然后$line
成为循环中执行的命令;并继续直到输入中没有其他行。
这仍然不适用于某些控制结构(如另一个循环),但在这种情况下它符合要求。
`ls | sed ...`
我有点像ls | sed ... | source -
会更漂亮,但不幸的是source
不理解-
意味着stdin
。
我认为你的解决方案是用反引号替换命令:http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html
见3.4.5节
为什么不使用source
呢?
$ ls | sed ... > out.sh ; source out.sh
要在bash 3.2(macos)上使用mark4o的解决方案,可以使用此字符串代替管道,如下例所示:
. /dev/stdin <<< "$(grep '^alias' ~/.profile)"
以上是关于如何在当前shell中执行命令的输出?的主要内容,如果未能解决你的问题,请参考以下文章