sau*_*rav 1 ssh shell-script quoting
我有一个脚本,我在其中从包含 .csv 文件的 csv 文件中读取SourceIp, DestinationIP,Source Ports, Destination Ports。
首先,我正在读取 sourceIp 并尝试对其执行 ssh(我能够成功完成),在这里我试图获得一个伪终端并希望执行一个 for 循环,该循环将迭代 sourcePorts(连字符分隔)和目的地端口。
输入文件内容:
10.X.X.9,10.X.X.23,8140-61613,1521-1524-1525-1526-1530-1531-8140-61613
Run Code Online (Sandbox Code Playgroud)
脚本 :
export lastSourceIP=""
export lastDestinationIP=""
export fqdn=""
export sourceFqdn=""
x=0
export username="sjain";
export location="/home/sjain/poc";
export baseLocation="10.X.X.9"
while IFS="," read f1 f2 f3 f4
do
x=$(($x+1))
TMP=$(mktemp)
TMP2=$(mktemp)
echo "Source IP : $f1"
echo "Destination IP : $f2"
echo "Source Ports : $f3"
echo "Destination Ports : $f4"
export sourceIP=$f1
export destIP=$(echo "$f2" | tr -d '\n')
export port=$(echo "$f3" | tr -d '\n')
export destinationPorts=$(echo "$f4" | tr -d '\n')
ssh -t -t $username@$sourceIP 'bash -s' <<ENDSSH
(IFS='-'; for sourceP in $port; do
(for destinationP in $destinationPorts; do
echo "$sourceP" - "$destinationP"
done;)
done;)
exit
ENDSSH
done < ipaddress.csv
Run Code Online (Sandbox Code Playgroud)
但是当我执行这个脚本时,它没有打印 sourceIP - DestinationIp 值。这里,是我在控制台上的输出。
输出:
Source IP : 10.X.X.9
Destination IP : 10.X.X.23
Source Ports : 8140-61613
Destination Ports : 1521-1524-1525-1526-1530-1531-8140-61613
tcgetattr: Inappropriate ioctl for device
(IFS='-'; for sourceP in 8140-61613; do
(for destinationP in 1521-1524-1525-1526-1530-1531-8140-61613; do
echo "" - ""
done;)
done;)
exit
[sjain@XXX.SERVER ~]$ (IFS='-'; for sourceP in 8140-61613; do
> (for destinationP in 1521-1524-1525-1526-1530-1531-8140-61613; do
> echo "" - ""
> done;)
> done;)
-
[sjain@XXX.SERVER ~]$ exit
exit
Connection to 10.X.X.9 closed
.
Run Code Online (Sandbox Code Playgroud)
预期输出:
8140-1521
8140-1524
.... and so on
Run Code Online (Sandbox Code Playgroud)
请帮助我做错的地方。
您需要确保在远程主机上取消对循环变量的引用:
ssh -t -t $username@$sourceIP 'bash -s' <<ENDSSH
IFS='-'
for sourceP in $port; do
for destinationP in $destinationPorts; do
echo "\$sourceP" - "\$destinationP"
done
done
ENDSSH
Run Code Online (Sandbox Code Playgroud)
使用所有括号为每次循环迭代启动一个子shell,这是您不需要的大量额外工作。
您不需要导出所有变量,只需导出需要在子进程环境中的变量。
这destIP=$(echo "$f2" | tr -d '\n')与destIP=$f2- 假设没有“内部”换行符没有什么不同。$(command substitution)删除尾随的换行符。