我不明白为什么我的脚本在第一行之后离开循环。看来它中断了,因为我在 deleteUser 函数中调用另一个脚本。
这是我的脚本的摘录:
[...]
function deleteUser
{
nfsserver="/local/scripts/find_home_in_nfs.sh ${1}"
ssh -n $nfsserver "rm -rf /home/${1}"
ssh ldap "sudo deleteUser ${1}"
userHome ${1}
}
cat myFile | while read line
do
username=`echo ${line} | awk -F" " '{print $1}'`
action=`echo ${line} | awk -F" " '{print $2}'`
if [ "${action}" == "d" ]; then
deleteUser ${username}
elif [ "${action}" == "a" ]; then
addUser ${username}
fi
done
我尝试重写脚本的简化版本,而不调用“find_home_in_nfs.sh”(它与所有 NFS 服务器进行大量 ssh 连接以查找主位置),并且它有效。
但我必须使用它,我无法修改它。有没有办法让这个 while 循环起作用?
答案1
您可以大大简化循环,如以下示例所示:
while read username action
do
if [ "${action}" == "d" ]; then
echo "deleteUser ${username}"
elif [ "${action}" == "a" ]; then
echo "addUser ${username}"
fi
done < myFile
答案2
基本问题是ssh
读取大部分文件。read line
从文件中读取第一行,然后它运行(除其他外),其中ssh -n $nfsserver "rm -rf /home/${1}"
(因为-n
)不从标准输入读取,然后它运行ssh ldap "sudo deleteUser ${1}"
没有从标准输入读取的内容-n
,因此读取它可以读取的所有内容(即整个文件的其余部分)并将其发送到远程计算机,远程计算机将忽略它。然后,下一次迭代开始,read line
尝试从文件中读取,但它位于末尾,因此退出循环。
您可以通过添加-n
其他命令(以及可能运行的ssh
任何其他命令)来解决此问题,ssh
和添加类似于</dev/null
可能从标准输入读取的所有其他命令的内容...但我更喜欢发送文件以通过标准输入以外的其他内容进行读取,这样可以跳过整个混乱。以下是如何使用 FD #3 发送和读取它:
while read line <&3; do
...
done 3<myFile
read
将此与@fpmurphy1的让处理字段分割的建议和@Kusalananda的使用相结合case
给出:
while read username action <&3
do
case "$action" in
d) deleteUser "$username" ;;
a) addUser "$username" ;;
*) echo "Unknown action: $action on user $username" >&2 ;;
esac
done 3< myFile
顺便说一句,如果您要一次添加和删除大量用户,我会尝试进一步优化它。在当前版本中,它为每个用户与每个服务器打开一个单独的 ssh 会话。打开到每台服务器的单个连接并通过该连接处理所有用户会更快。缺点:如果您不小心,错误处理会变得更加复杂。
答案3
更简单的代码,使用bash
关联数组:
declare -A a=([a]=add [d]=delete)
while read username action; do
${a[$action]}User ${username}
done < myFile