linux - 将变量传递给子 shell 时出现问题

标签 linux bash variables global-variables subshell

所以这是我的问题,我写了这个脚本,我在其中导出两个变量,但是它们没有进入子 shell。

此脚本的目的是更改用户密码并清除 CentOS 和 Ubuntu 主机的 pam_tally。

一点背景是这个环境的用户由 puppet 管理,但密码都是本地的,ssh key 也不允许(这是一成不变的,无法更改,所以我必须使用我得到的东西)原因是每次登录都必须是手动的(即使 session 数也限制为两个,因此您甚至无法有效地使用 csshX)。

这是我的脚本

    #!/bin/bash

echo "Please enter user whose password you want to change"
read NEWUSER
echo "Please enter new password for user"
read -s -p "Temp Password:" TEMPPASSWORD

PASSWORD=$TEMPPASSWORD
export PASSWORD
NEWUSER2=$NEWUSER
export NEWUSER2

for i in HOST{cluster1,cluster2,cluster3}0{1..9}
do

ping -c 2 $i && (echo $i ; ssh -t $i '

sudo pam_tally2 --user=$NEWUSER2 --reset

echo -e "$PASSWORD\n$PASSWORD" | sudo passwd $NEWUSER2

sudo chage -d 0 $NEWUSER2

')

done

最佳答案

您正在使用 ssh 连接到远程主机并在该主机上运行脚本。 ssh 不会将本地环境导出到远程 session ,而是在远程主机上执行登录,根据远程用户在远程主机上的配置设置环境。

我建议您通过要执行的命令 传递所有需要的值。这可以这样做:

ssh -t $i '
  sudo pam_tally2 --user='"$NEWUSER2"' --reset
  echo -e "'"$PASSWORD"'\n'"$PASSWORD"'" | sudo passwd '"$NEWUSER2"'
  sudo chage -d 0 '"$NEWUSER2"

仔细观察它是如何使用引号的。在每次使用变量的情况下,我都会终止单引号字符串(使用 '),然后添加变量的双引号使用(例如 "$PASSWORD") 然后再次开始单引号字符串(再次使用 ')。这样,执行 ssh 命令的 shell 将已经扩展变量,因此您无需将它们传递到远程 shell。

但请注意,密码中的特殊字符(如 "' 或可能是一堆其他字符)可能意味着麻烦使用这个简单的机制。为了避免这种情况,您需要使用 printf 命令的 %q 格式说明符在传递值之前引用您的值:

ssh -t "$i" "$(printf '
  sudo pam_tally2 --user=%q --reset
  { echo %q; echo %q; } | sudo passwd %q
  sudo chage -d 0 %q' \
    "$NEWUSER2" "$PASSWORD" "$PASSWORD" "$NEWUSER2" "$NEWUSER2")"

关于linux - 将变量传递给子 shell 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32019076/

相关文章:

linux - 如何在 unix 中更改 .csv 文件中的日期格式

bash -/dev/stdin 与 herestring

php - 在php函数中一次使用所有全局变量

matlab - 如何将变量移入和移出类似于 MATLAB 中的 LOAD 和 SAVE 的结构?

c - 如何从 PCM 获取缓冲区?

linux - 如何在 Linux bash 中提取带条件的 csv 文件的第 n 列?

windows - 从 Cygwin bash 脚本执行 Windows 命令

file - 在 Bash 中按创建时间排序文件到毫秒

java - 无法从 for 循环中获取总和

c - 需要在错误处理中替换已弃用的数组