SSH私钥登录多远程主机脚本循环终止问题解决
解决Bash脚本批量SSH仅处理第一台主机的问题
问题原因
SSH命令默认会读取标准输入(stdin),而你的while循环是从输入文件读取stdin内容。第一次执行SSH时,会把输入文件中剩下的所有行当作自己的输入消耗掉,导致循环只处理第一台主机就终止。
解决方法
方法1:给SSH添加-n参数
-n参数会让SSH从/dev/null读取输入,避免占用脚本的stdin,修改所有SSH命令即可:
#!/bin/bash # Check if the user provided a file if [ $# -eq 0 ]; then echo "provide input file" echo "Usage: $0 <input_file>" exit 1 fi # Read input file input_file=$1 # Check if the file exists if [ ! -f "$input_file" ]; then echo "Error: File $input_file not found." exit 1 fi # Read each line from the input file while IFS=, read -r ip_address username; do echo "Machine IP: $ip_address" # Connect to the server via SSH and execute the command echo "System Users:" ssh -n -i /home/subash/Desktop/privatekey "$username"@"$ip_address" "ls -l /home/ | awk 'NR >1 {print \$3}'" 2>/dev/null echo "---------------" echo "Disk details:" ssh -n -i /home/subash/Desktop/privatekey "$username"@"$ip_address" 'lsblk -o name,model,size,ro,mountpoint,type | grep -e part -e disk' 2>/dev/null echo "---------------" echo "OPERATING SYSTEM:" ssh -n -i /home/subash/Desktop/privatekey "$username"@"$ip_address" "cat /etc/os-release | grep '^NAME' | cut -d'=' -f2-" 2>/dev/null echo "---------------" done < "$input_file"
注:顺便统一了私钥的绝对路径,避免后续SSH命令找不到私钥的问题
方法2:重定向SSH输入到/dev/null
如果不想用-n参数,也可以在每个SSH命令末尾加上< /dev/null,效果和-n一致:
ssh -i /home/subash/Desktop/privatekey "$username"@"$ip_address" "ls -l /home/ | awk 'NR >1 {print \$3}'" 2>/dev/null < /dev/null
方法3:使用独立文件描述符读取输入
把输入文件绑定到独立的文件描述符(比如3),让while循环从这个描述符读取,彻底避免和SSH的stdin冲突:
#!/bin/bash # Check if the user provided a file if [ $# -eq 0 ]; then echo "provide input file" echo "Usage: $0 <input_file>" exit 1 fi # Read input file input_file=$1 # Check if the file exists if [ ! -f "$input_file" ]; then echo "Error: File $input_file not found." exit 1 fi # 绑定输入文件到文件描述符3 exec 3< "$input_file" # 从描述符3读取每行内容 while IFS=, read -r ip_address username <&3; do echo "Machine IP: $ip_address" # Connect to the server via SSH and execute the command echo "System Users:" ssh -i /home/subash/Desktop/privatekey "$username"@"$ip_address" "ls -l /home/ | awk 'NR >1 {print \$3}'" 2>/dev/null echo "---------------" echo "Disk details:" ssh -i /home/subash/Desktop/privatekey "$username"@"$ip_address" 'lsblk -o name,model,size,ro,mountpoint,type | grep -e part -e disk' 2>/dev/null echo "---------------" echo "OPERATING SYSTEM:" ssh -i /home/subash/Desktop/privatekey "$username"@"$ip_address" "cat /etc/os-release | grep '^NAME' | cut -d'=' -f2-" 2>/dev/null echo "---------------" done # 关闭文件描述符3 exec 3<&-
内容的提问来源于stack exchange,提问作者Subash
相关产品推荐
相关产品推荐

