如何在bash变量中使用linux命令

如何在bash变量中使用linux命令,linux,bash,variables,Linux,Bash,Variables,我正在尝试创建一个bash脚本,以执行与以下命令相同的操作: dig -x 8.8.8.8 | grep PTR | cut -d ' ' -f 2 | grep google | cut -f 5 输出为google-public-dns-a.google.com 现在,我创建了脚本test.sh,如下所示: #!/bin/bash IP=$1 output1=$(dig -x $IP) grepg="grep PTR | cut -d ' ' -f 2 | grep google | cu

我正在尝试创建一个bash脚本,以执行与以下命令相同的操作:

dig -x 8.8.8.8 | grep PTR | cut -d ' ' -f 2 | grep google | cut -f 5
输出为google-public-dns-a.google.com

现在,我创建了脚本test.sh,如下所示:

#!/bin/bash
IP=$1
output1=$(dig -x $IP)
grepg="grep PTR | cut -d ' ' -f 2 | grep google | cut -f 5"
go=$($output1 | $grepg)
echo $go
并将脚本称为./test.sh 8.8.8.8。但是会有错误。如何使用引号有效地将Linux命令存储在bash变量中? 谢谢

为什么不简单地说:

dig -x "$1" | grep PTR | cut -d ' ' -f 2 | grep google | cut -f 5
为什么不简单地:

dig -x "$1" | grep PTR | cut -d ' ' -f 2 | grep google | cut -f 5

您的管道命令链可以缩短为单个awk命令:

dig -x 8.8.8.8 | awk '/PTR[[:space:]]/{print $NF}'
google-public-dns-a.google.com
如果你想在同一行中搜索谷歌:

dig -x 8.8.8.8| awk '/PTR[[:space:]]/ && /google/ {print $NF}'
要将其输出存储在bash变量中,请使用:

go=$(dig -x 8.8.8.8| awk '/PTR[[:space:]]/{print $NF}')

您的管道命令链可以缩短为单个awk命令:

dig -x 8.8.8.8 | awk '/PTR[[:space:]]/{print $NF}'
google-public-dns-a.google.com
如果你想在同一行中搜索谷歌:

dig -x 8.8.8.8| awk '/PTR[[:space:]]/ && /google/ {print $NF}'
要将其输出存储在bash变量中,请使用:

go=$(dig -x 8.8.8.8| awk '/PTR[[:space:]]/{print $NF}')
output1存储dig-x$IP的结果,而不是命令本身,因为您使用$

grepg将命令存储为字符串,这很好,但会给您带来一些意想不到的结果

在这一行:

go=$($output1 | $grepg) 
它试图将dig的输出通过管道传输到一个名为grep PTR | cut-d'-f2 | grep google | cut-f5的程序中

您可能想要的是:

#!/bin/bash
IP=$1
output1="dig -x $IP"
grepg="grep PTR | cut -d ' ' -f 2 | grep google | cut -f 5"
go=$(eval $output1 | eval $grepg)
echo $go
dig命令作为字符串存储在output1中,就像grepg存储另一个命令一样

此外,这里也需要eval。如果没有eval,它认为整个字符串是程序名,而不是后跟参数、管道等的程序名

这意味着它正在寻找一个名为grep PTR | cut-d''-f2 | grep google | cut-f5的程序,而不是寻找grep后跟一个参数,后跟一个管道等等。

output1存储dig-x$IP的结果,而不是命令本身,因为您使用$

grepg将命令存储为字符串,这很好,但会给您带来一些意想不到的结果

在这一行:

go=$($output1 | $grepg) 
它试图将dig的输出通过管道传输到一个名为grep PTR | cut-d'-f2 | grep google | cut-f5的程序中

您可能想要的是:

#!/bin/bash
IP=$1
output1="dig -x $IP"
grepg="grep PTR | cut -d ' ' -f 2 | grep google | cut -f 5"
go=$(eval $output1 | eval $grepg)
echo $go
dig命令作为字符串存储在output1中,就像grepg存储另一个命令一样

此外,这里也需要eval。如果没有eval,它认为整个字符串是程序名,而不是后跟参数、管道等的程序名


这意味着它正在寻找一个名为grep PTR | cut-d''-f2 | grep google | cut-f5的程序,而不是寻找grep后跟一个参数,后跟一个管道等等。

这里有几个问题

首先,您试图将变量$ouptut1的内容作为命令执行,该变量只是dig输出;这不是命令。你可能是指echo$output1

然后,您尝试将变量$grepg的内容作为管道执行。但是将一行解析为复合命令的组件管道是在参数扩展之前发生的复合命令。因此,如果您执行类似这样的操作:

foo="echo hello | grep hi"
$foo
首先将其分解为单个简单命令,然后扩展该命令,然后将其解析为参数。因此,这相当于运行:

echo hello "|" grep hi
一般来说,在变量中存储要计算的文本字符串不是一个好主意。有一些非常特殊的情况下,你可能想这样做,但在几乎所有的情况下,可能你的情况下,有一个更好的方法来做。我将警告您不要这样做,但如果您确实想将字符串作为命令进行求值,可以使用eval,例如:

go=$(echo $output1 | eval $grepg)
您似乎想要定义一个shell函数。如果您想多次重用该管道,在其中运行多个不同的值,只需定义一个shell函数。该函数是一个单独的命令,相当于包含的命令:

function grepg() {
    grep PTR | cut -d ' ' -f 2 | grep google | cut -f 5
}

go=$(echo $output1 | grepg)
为了进一步简化代码,可以避免使用所有中间变量。如果您只是将dig命令的结果通过管道传输到grepg中,那么在执行此操作之前不需要将其保存在变量中。如果您只是想将结果回显到stdout,那么您也不需要将其存储在变量中,您可以让输出转到stdout:

#!/bin/bash
IP=$1
function grepg() {
    grep PTR | cut -d ' ' -f 2 | grep google | cut -f 5
}

dig -x $IP | grepg
我在这里假设您希望将函数分解出来,以便可以在脚本中多次使用它;如果没有,如果您只打算使用一次,您可以进一步简化为:

#!/bin/bash
IP=$1
dig -x $IP | grep PTR | cut -d ' ' -f 2 | grep google | cut -f 5
请注意,如果您希望在变量中存储这样的管道,以便可以使用其他代码在两个函数之间进行选择,并根据某些条件应用其中一个函数或另一个函数,我建议您定义如上所述的函数,然后只在变量中存储单个函数名。这将按照您期望的方式工作:

function grepg() {
    grep PTR | cut -d ' ' -f 2 | grep google | cut -f 5
}

function grepf() {
    # do something else, I'm not creative enough to come up with a good example
}

if [ "$2" = "foo" ]
then
    func=grepg
else
    func=grepf
fi

dig -x $IP | $func

这里有几个问题

首先,您试图将变量$ouptut1的内容作为命令执行,该变量只是dig输出;这不是命令。你可能是指echo$output1

然后您尝试执行var的内容 可用$grepg作为管道。但是将一行解析为复合命令的组件管道是在参数扩展之前发生的复合命令。因此,如果您执行类似这样的操作:

foo="echo hello | grep hi"
$foo
首先将其分解为单个简单命令,然后扩展该命令,然后将其解析为参数。因此,这相当于运行:

echo hello "|" grep hi
一般来说,在变量中存储要计算的文本字符串不是一个好主意。有一些非常特殊的情况下,你可能想这样做,但在几乎所有的情况下,可能你的情况下,有一个更好的方法来做。我将警告您不要这样做,但如果您确实想将字符串作为命令进行求值,可以使用eval,例如:

go=$(echo $output1 | eval $grepg)
您似乎想要定义一个shell函数。如果您想多次重用该管道,在其中运行多个不同的值,只需定义一个shell函数。该函数是一个单独的命令,相当于包含的命令:

function grepg() {
    grep PTR | cut -d ' ' -f 2 | grep google | cut -f 5
}

go=$(echo $output1 | grepg)
为了进一步简化代码,可以避免使用所有中间变量。如果您只是将dig命令的结果通过管道传输到grepg中,那么在执行此操作之前不需要将其保存在变量中。如果您只是想将结果回显到stdout,那么您也不需要将其存储在变量中,您可以让输出转到stdout:

#!/bin/bash
IP=$1
function grepg() {
    grep PTR | cut -d ' ' -f 2 | grep google | cut -f 5
}

dig -x $IP | grepg
我在这里假设您希望将函数分解出来,以便可以在脚本中多次使用它;如果没有,如果您只打算使用一次,您可以进一步简化为:

#!/bin/bash
IP=$1
dig -x $IP | grep PTR | cut -d ' ' -f 2 | grep google | cut -f 5
请注意,如果您希望在变量中存储这样的管道,以便可以使用其他代码在两个函数之间进行选择,并根据某些条件应用其中一个函数或另一个函数,我建议您定义如上所述的函数,然后只在变量中存储单个函数名。这将按照您期望的方式工作:

function grepg() {
    grep PTR | cut -d ' ' -f 2 | grep google | cut -f 5
}

function grepf() {
    # do something else, I'm not creative enough to come up with a good example
}

if [ "$2" = "foo" ]
then
    func=grepg
else
    func=grepf
fi

dig -x $IP | $func

@IMSoP:其实并不需要grep,因为这个IP解析为google-public-dns-a.google。很明显,8.8.8.8是可变的,但google是不变的。它没有解释为什么这是必要的,但也没有证据表明它不是。@IMSoP:grep并不是真的需要,因为这个IP解析为google-public-dns-a.google.com这一问题很清楚,8.8.8.8是可变的,但google是不变的。它没有解释为什么这是必要的,但也没有证据表明它不是。我用它来清楚地表达我的怀疑。我知道这可以一步完成,但我想了解如何将命令存储在变量中并用于以后的使用。我用这个来清楚地表达我的疑问。我知道这可以一步完成,但我想了解如何将命令存储在变量中并用于以后的使用。是的,这是我真正关注的是,这是我真正关注的bash。使用python@ealfonso抛弃蟒蛇。编写汇编代码。我能赢得酷炫程序员大赛吗?Python与汇编完全相反code@ealfonso无聊的;cut可能比正则表达式更容易中断,但它可能不会-您可能有定义良好的字段,但不知道其中包含什么。shell脚本和Python都允许您以多种不同的风格使用它们。就像我说的,这都是主观的,这就是讨论的开始。我想我们都开始把这件事看得太严肃了,为此我向你道歉。是的,我也为自己太过个人化而感到内疚。我很高兴你向我提出了挑战,我认为这是一次比我最初的评论所暗示的更好、更具体、更有益的讨论。使用python@ealfonso抛弃蟒蛇。编写汇编代码。我能赢得酷炫程序员大赛吗?Python与汇编完全相反code@ealfonso无聊的;cut可能比正则表达式更容易中断,但它可能不会-您可能有定义良好的字段,但不知道其中包含什么。shell脚本和Python都允许您以多种不同的风格使用它们。就像我说的,这都是主观的,这就是讨论的开始。我想我们都开始把这件事看得太严肃了,为此我向你道歉。是的,我也为自己太过个人化而感到内疚。我很高兴你向我提出了挑战,我认为这次讨论比我最初的评论所暗示的更好、更具体、更有益。