bash 如何从变量运行脚本命令?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3469705/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to run script commands from variables?
提问by stacker
I tried to run commands using pipes.
我尝试使用管道运行命令。
Basic:
基本:
single="ls -l"
$single
which works as expected
它按预期工作
Pipes:
管道:
multi="ls -l | grep e"
$multi
ls: |: No such file or directory
ls: grep: No such file or directory
ls: e: No such file or directory
...no surprise
...没有惊喜
bash < $multi
$multi: ambiguous redirect
next try
下次试试
bash $multi
/bin/ls: /bin/ls: cannot execute binary file
Only
仅有的
echo $multi > tmp.sh
bash tmp.sh
worked.
工作。
Is there a way to execute more complex commands without creating a script for execution?
有没有办法在不创建执行脚本的情况下执行更复杂的命令?
回答by bukzor
You're demonstrating the difference between the shell and the kernel.
您正在演示 shell 和内核之间的区别。
"ls -l" is executable by the system execve() call. You can man execvefor details, but that's probably too much detail for you.
“ls -l”可由系统 execve() 调用执行。您可以man execve了解详细信息,但这对您来说可能太多了。
"ls -l | grep e" needs shell interpretation to set up the pipe. Without using a shell, the '|' character is just passed into execve() as an argument to ls. This is why you see the "No such file or directory" errors.
"ls -l | grep e" 需要 shell 解释来设置管道。不使用外壳,'|' 字符只是作为参数传递给 execve() 给 ls。这就是您看到“没有这样的文件或目录”错误的原因。
Solution:
解决方案:
cmd="ls -l | grep e"
bash -c "$cmd"
回答by mikeserv
You need a heredocto do this correctly. In answer to POSIX compliant way to see if a function is defined in an sh script, I detailed how to read a script into a variable, programmatically parse it for information and/or modify it as necessary, then execute it from another script or shell function. That's basically what you're trying to do, and the heredocmakes it possible because it provides a file descriptor:
你需要一个heredoc来正确地做到这一点。在回答POSIX 兼容方式以查看函数是否在 sh 脚本中定义时,我详细介绍了如何将脚本读入变量、以编程方式解析它以获取信息和/或根据需要修改它,然后从另一个脚本或 shell 执行它功能。这基本上就是你想要做的事情,并且heredoc因为它提供了一个文件描述符而使它成为可能:
% multi='ls -l | grep e'
% sh <<_EOF_
> ${multi}
> _EOF_
< desired output >
That would solve your simple example case. See my other answer for more.
那将解决您的简单示例案例。查看我的另一个答案以获取更多信息。
-Mike
-麦克风
回答by ghostdog74
when you want to run commands with pipes, just run it. Don't ever put the command into a variable and try to run it. Simply execute it
当你想用管道运行命令时,只需运行它。永远不要将命令放入变量并尝试运行它。简单的执行一下
ls -l |grep
ls -l |grep
If you want to capture the output, use $()
如果要捕获输出,请使用 $()
var=$(ls -l |grep .. )
var=$(ls -l |grep .. )

