在脚本shell中进行变量扩展

时间:2012-10-22 13:50:54

标签: shell ssh

我的代码是:

nb_lignes=`wc -l $1 | cut -d " " -f1`
for i in $(seq $(($nb_lignes - 1)) )
do
machine=`head $1 -n $i | tail -1`
machine1=`head $1 -n $nb_lignes | tail -1`
ssh root@$machine -x " scp /home/file.txt root@$machine1:/home && rm -r /home/file.txt"
done

$ machine1是变量还是字符串?如果是字符串,我该如何更改它? - 添加引号?

3 个答案:

答案 0 :(得分:2)

$machine将扩展为head $1 -n $i | tail -1结果,$machine1将扩展为head $1 -n $nb_lignes | tail -1结果。

你可以自己想出来。

顺便说一下,ssh root@ ......

答案 1 :(得分:1)

$machine1将展开以提供变量machine1的值,因为您使用的是双引号"。如果您使用过单引号',那么它就不会被展开。

一种可能的混淆是当您在其他文本中嵌入变量时。在这种情况下你很好,因为尾随字符是:root@$machine1:/home),它不是Bash变量名中的有效字符。有些shell(csh)不会喜欢它,如果你不确定那么你可以使用{ }分隔变量名,例如:

root@${machine1}:/home

答案 2 :(得分:0)

重写的答案

无论ssh root滥用了什么......(我更喜欢使用curl来实现此目的,但您必须自己编写 collectFiles.php ;)< / p>

好的,这样做的目的是将主机列表的最后行作为destination,从列表的其余部分发送文件。你可以:

首先是Posix shell:

下测试
tac $1  | (
    srcFile=/home/file.txt i=1
    read destHost
    while read collectHost ;do
        destFile=`printf "root@%s:/home/fileHost_%-12s_%03d.txt" \
            $destHost $collectHost $i`
        i=$((i+1))
        echo ssh $collectHost -x "curl -H 'Filename: $destFile' \
            --data-binary '@$srcFile http:/$destHost/collectFiles.php && \
                rm $srcFile"
        done
)

echo将被删除)

现在:

操纵变量提供了构建命令的好方法,有一个 完全可用的样本

#!/bin/bash

mapfile flist <$1

dstCmdFmt="curl -H 'Filename: %s' --data-binary '@%s' http://%s/%s && rm %s"
dstRcvPhp=collectfiles.php
srcFile=/home/file.txt

for ((i=0;i<${#flist[@]}-1;i++));do
    printf -v destFile "fileHost_%-12s_%03d.txt" ${flist[i]} $[1+i]
    printf -v cmd "$dstCmdFmt" \
        ${destFile// /_} $srcFile ${flist[@]:${#flist[@]}-1} $dstRcvPhp $srcFile
    echo ssh ${flist[i]} -x "$cmd"
done

尝试使用文件:

cat <<eof > testfile
machineA
OtherMachine
AnotherHost
DestinationHost
eof

./script.sh testfile
ssh machineA -x curl -H 'Filename: fileHost_machineA_____001.txt' --data-binary '@/home/file.txt' http://DestinationHost/collectfiles.php && rm /home/file.txt
ssh OtherMachine -x curl -H 'Filename: fileHost_OtherMachine_002.txt' --data-binary '@/home/file.txt' http://DestinationHost/collectfiles.php && rm /home/file.txt
ssh AnotherHost -x curl -H 'Filename: fileHost_AnotherHost__003.txt' --data-binary '@/home/file.txt' http://DestinationHost/collectfiles.php && rm /home/file.txt

旧答案

而不是......

nb_lignes=`wc -l <$1`
machine1=`sed -ne ${nb_lignes}p <$1`
for i in `seq $(($nb_lignes - 1))` ;do
    machine=`sed -ne ${i}p <$1`
    ssh  root@$machine -x " scp /home/file.txt root@$machine1:/home && rm -r /home/file.txt"
  done

但是...

如果来自每个machine,您确实将不同的file.txt(但具有相同名称)发送到同一目标目录中的同一唯一machine,您将每次覆盖以前发送的文件