我正在尝试运行一个看起来像这样的 for 循环
cat all_data |
awk '{print $1 " "$2" " $3}' |
while read inst type serial ; do
echo $inst
if [ `echo ${inst} | cut -d '-' -f2` = H3 ]; then
ssh -t username@hostname3 "sudo ls"
elif [ `echo ${inst} | cut -d '-' -f2` = H2 ] ; then
ssh -t username@hostname2 "sudo ls"
elif [ `echo ${inst} | cut -d '-' -f2` = H1 ]; then
ssh -t username@hostname1 "sudo ls"
fi
done
我无法运行 ssh -t 部分,它说不会分配 psuedo 终端,因为 stdin 不是终端 sudo:不存在 tty,也没有指定 Askpass 程序 我尝试过使用 -t -t 和 -n,但没有运气。我无法从运行此命令的主机编辑 visudo 文件。
编辑
$ cat all_data
ABC-DIF2 DELL-800 60999
ABC-DIF3 HP-DL340 J0777
ABC-DIF4 DELL-800 P0087
.
.
.
all_data 包含 1000 个类似条目。我正在尝试执行以下操作。 60999,J0777...是我需要运行命令的实体。
所以我试图读取每一行,拆分并检查与实体对应的 DIF 编号是什么。
例如,如果我读取 DIF2,则意味着我需要 ssh 到 hostname2 并运行命令以获取 60999 上的数据
如果我读到 DIF3,则意味着实体 J0777 只能从主机名 3 运行。
答案1
旁白:你的(例子?)cat
和awk
是无用的,你不需要重复echo|cut
和测试。
澄清您需要输入远程 sudo 的密码后,您需要两个都让我们ssh
使用终端输入并指定-t
,以便将该输入作为 PTY 转发。这基本上是一个骗局SSH 导致 while 循环停止尽管您没有达到相同的症状。
方法 1:为循环重定向(或管道)stdin 但重定向它后退对于 SSH
while read inst type serial; do
case ${inst#*-} in
(DIF1) ssh </dev/tty -t user@host1 "sudo blah";;
(DIF2) ssh </dev/tty -t user@host2 "sudo blech";;
# more as needed
esac
done <alldata
# or cat/awk/whatever | while read ... done
方法 2:对所有数据使用不同的单元号(不是标准输入)
while read <&3 inst type serial; do
case ${inst#*-} in
(DIF1) ssh -t user@host1 "sudo blah";;
(DIF2) ssh -t user@host2 "sudo blech";;
# more
esac
done 3<alldata
# or while read ... done 3< <(cat/awk/whatever) with zsh/bash
方法 3 是使用一个for
循环(尽管您的 Q 说您这样做了,但您没有这样做),它在没有任何通道的情况下从其参数中读取。对于您最初仅实际使用一个字段的 Q 来说,这很简单:
IFS='
' # split on newline only
set -o noglob # disable globbing
for inst in $(awk '{print $1}' alldata); do
# as for method 2
done
但你的编辑说你想使用至少一个其他字段,所以你需要一些更丑陋的东西,比如:
IFS='
' # split on newline only
set -o noglob # disable globbing
for line in $(awk '{print $1":"$2":"$3}' alldata); do
IFS=:; set -- $line; inst=$1; serial=$3;
# as before
done