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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 22:29:11  来源:igfitidea点击:

How to run script commands from variables?

linuxbashshellcommand-line

提问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 .. )