使用shell脚本ssh到不同的节点

时间:2017-03-13 12:25:02

标签: linux shell ssh

我使用下面的代码来ssh到不同的节点,并查找用户是否存在。如果用户不存在,则会创建它。

如果我不做ssh,脚本工作正常但如果我做ssh则失败。

如何使用此脚本浏览不同的节点?

for node in `nodes.txt`
usr=root

ssh $usr@$node 
do
if [ $(id -u) -eq 0 ]; then
    read -p "Enter username : " username
    read -s -p "Enter password : " password
    egrep "^$username" /etc/passwd >/dev/null
    if [ $? -eq 0 ]; then
        echo "$username exists!"
        exit 1
    else
        pass=$(perl -e 'print crypt($ARGV[0], "password")' $password)
        useradd -m -p $pass $username
        [ $? -eq 0 ] && echo "User has been added to system!" || echo "F
ailed to add a user!"
    fi
else
    echo "Only root may add a user to the system"
    exit 2
fi
done

2 个答案:

答案 0 :(得分:1)

您的脚本存在严重的语法错误。我想开头的for循环就是你试图添加的东西,但你完全打破了这个过程中的脚本。

循环文件中的行的语法是

while read -r line; do
    .... # loop over "$line"
done <nodes.txt

(或稍微for line in $(cat nodes.txt); do ...但这有多个问题;有关详细信息,请参阅http://mywiki.wooledge.org/DontReadLinesWithFor

如果意图是在ssh中实际运行脚本的其余部分,则需要将其传递给ssh命令。像这样:

while read -r node; do
   read -p "Enter user name: " username
   read -p -s "Enter password: "
   ssh root@"$node" "
       # Note addition of -q option and trailing :
       egrep -q '^$username:' /etc/passwd ||
       useradd -m -p \"\$(perl -e 'print crypt(\$ARGV[0], \"password\")' \"$password\")" '$username'" </dev/null
done <nodes.txt

当然,传递给ssh的命令可能是任意复杂的,但您要避免在root权限的远程脚本中进行交互式I / O,并且通常要确保远程命令是安静的并且尽可能健壮。

反模式command; if [ $? -eq 0 ]; then ...笨拙但很常见。 if的目的是运行命令并检查其结果代码,因此这更好,更具惯用性if command; then ...(可以更简洁地编写command && ...或{{1}如果您只需要完整的长手! command || ... / then / else结构的ifthen部分。

答案 1 :(得分:0)

也许你应该只通过ssh做远程任务。所有其余的都在当地运行。

ssh $user@$node useradd -m -p $pass $username

Owner.csv

如果要在所有节点上创建相同的用户,最好在循环外询问用户名和密码。