如何设置一个variables来自Bash命令的输出?
我正在为涉及使用Bash的工作进行简单的脚本编写项目。 我有一个非常简单的脚本,如下所示:
#!/bin/bash VAR1="$1" VAR2="$2" MOREF='sudo run command against $VAR1 | grep name | cut -c7-' echo $MOREF
当我从命令行运行这个脚本并传递它的参数,我没有得到任何输出。 但是,当我运行$MOREF
variables中包含的命令时,我能够得到输出。 我想知道如何将一个需要在脚本中运行的命令的结果保存到一个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中空间是非常重要的,所以如果你想让你的命令按原样运行,不用再引入空格。
-
下面给L分配harshil,然后打印出来
L=$"harshil" echo "$L"
-
接下来将命令tr的输出分配给L2。 tr正在另一个variablesL1上运行。
L2=$(echo "$L1" | tr [:upper:] [:lower:])