如何设置一个variables来自Bash命令的输出?

我正在为涉及使用Bash的工作进行简单的脚本编写项目。 我有一个非常简单的脚本,如下所示:

#!/bin/bash VAR1="$1" VAR2="$2" MOREF='sudo run command against $VAR1 | grep name | cut -c7-' echo $MOREF 

当我从命令行运行这个脚本并传递它的参数,我没有得到任何输出。 但是,当我运行$MOREFvariables中包含的命令时,我能够得到输出。 我想知道如何将一个需要在脚本中运行的命令的结果保存到一个variables,然后在屏幕上输出该variables?

除了反引号,你可以使用$() ,我发现它更容易阅读,并允许嵌套。

 OUTPUT="$(ls -1)" echo "${OUTPUT}" 

引用( " )对保存多行值很重要。

你正在使用错误的撇号。 你需要,而不是。 这个字符被称为“反引号”(或“重音符号”)。

喜欢这个:

 #!/bin/bash VAR1="$1" VAR2="$2" MOREF=`sudo run command against $VAR1 | grep name | cut -c7-` echo $MOREF 

正如他们已经指出的那样,你应该使用“反引号”。

另外提出的$(command)可以工作,而且它也更容易阅读,但是请注意,它只适用于bash或korn shell(以及从这些shell派生的shell),所以如果你的脚本必须在各种Unix系统,你应该更喜欢旧的反引号符号。

我知道三种方法:

1)function适用于这样的任务:

 func (){ ls -l } 

通过说func调用它

2)另一个合适的解决scheme可以是eval:

 var="ls -l" eval $var 

3)第三个是直接使用variables:

 var=$(ls -l) OR var=`ls -l` 

你可以很好地得到第三个解决scheme的输出:

 echo "$var" 

而且也是讨厌的方式:

 echo $var 

只是为了不同:

 MOREF=$(sudo run command against $VAR1 | grep name | cut -c7-) 

一些bash技巧,我用来从命令设置variables

第一个简单的旧的兼容的方式

 myPi=`echo '4*a(1)' | bc -l` echo $myPi 3.14159265358979323844 

大部分兼容,第二种方式

由于嵌套可能变得沉重,为此实施括号

 myPi=$(bc -l <<<'4*a(1)') 

嵌套样本:

 SysStarted=$(date -d "$(ps ho lstart 1)" +%s) echo $SysStarted 1480656334 

阅读多个variables(用bashisms

 df -k / Filesystem 1K-blocks Used Available Use% Mounted on /dev/dm-0 999320 529020 401488 57% / 

如果我只想使用值:

 array=($(df -k /)) 

你可以看到数组variables:

 declare -p array declare -a array='([0]="Filesystem" [1]="1K-blocks" [2]="Used" [3]="Available" [ 4]="Use%" [5]="Mounted" [6]="on" [7]="/dev/dm-0" [8]="999320" [9]="529020" [10]= "401488" [11]="57%" [12]="/")' 

然后:

 echo ${array[9]} 529020 

但我更喜欢这个:

 { read foo ; read filesystem size used avail prct mountpoint ; } < <(df -k /) echo $used 529020 

read将只是跳过标题行。

关于sudo cmd | grep ... | cut ... sudo cmd | grep ... | cut ...

 shell=$(cat /etc/passwd | grep $USER | cut -d : -f 7) echo $shell /bin/bash 

(请避免无用的cat !所以这只是1叉less:

 shell=$(grep $USER </etc/passwd | cut -d : -f 7) 

所有pipe道( | )都意味着叉子。 另一个进程必须运行,访问磁盘,库调用等。

所以使用sed作为示例,会将subprocess限制为只有一个分支

 shell=$(sed </etc/passwd "s/^$USER:.*://p;d") echo $shell 

但是对于许多行为,大部分是小文件, bash可以自己完成这项工作:

 while IFS=: read -a line ; do [ "$line" = "$USER" ] && shell=${line[6]} done </etc/passwd echo $shell /bin/bash 

如果你想用multiline / multiple命令来完成,你可以这样做:

 output=$( bash <<EOF #multiline/multiple command/s EOF ) 

要么:

 output=$( #multiline/multiple command/s ) 

例:

 #!/bin/bash output="$( bash <<EOF echo first echo second echo third EOF )" echo "$output" 

输出:

 first second third 

使用heredoc你可以简单的把事情简单化,把你的长单行代码分解成多行代码。 另一个例子:

 output="$( ssh -p $port $user@$domain <<EOF #breakdown your long ssh command into multiline here. EOF )" 

您可以使用back-ticks(也称为口音坟墓)或$() 。 像as-

 OUTPUT=$(x+2); OUTPUT=`x+2`; 

两者都有相同的效果。 但是OUTPUT = $(x + 2)更具可读性,而且是最新的。

这是另一种方式,适用于某些无法正确突出显示您创build的所有复杂代码的文本编辑器。

 read -r -d '' str < <(cat somefile.txt) echo "${#str}" echo "$str" 

有些人可能觉得这很有用。 variablesreplace中的整数值,其中的技巧是使用$(())双括号:

 N=3 M=3 COUNT=$N-1 ARR[0]=3 ARR[1]=2 ARR[2]=4 ARR[3]=1 while (( COUNT < ${#ARR[@]} )) do ARR[$COUNT]=$((ARR[COUNT]*M)) (( COUNT=$COUNT+$N )) done 

设置variables时,确保在=号之前和/或之后没有空格 。 从字面上花了一个小时试图想出这个,尝试各种解决scheme! 这并不酷。

正确:

 WTFF=`echo "stuff"` echo "Example: $WTFF" 

将失败 ,错误:(东西:没有find或类似)

 WTFF= `echo "stuff"` echo "Example: $WTFF" 

这里有两种方法:请记住,在bash中空间是非常重要的,所以如果你想让你的命令按原样运行,不用再引入空格。

  1. 下面给L分配harshil,然后打印出来

     L=$"harshil" echo "$L" 
  2. 接下来将命令tr的输出分配给L2。 tr正在另一个variablesL1上运行。

     L2=$(echo "$L1" | tr [:upper:] [:lower:])