我有一个交互式脚本,用于比较本地目录和远程目录。我希望用户能够提供远程用户的名称、远程服务器的名称以及脚本应比较的两个路径(本地和远程应相同)(例如:read -p“要比较的目录路径:” dir)。以下是脚本交互式部分的片段。
read -p "Specify path of directory to check: " path
read -p "Specify remote user: " user
read -p "Specify remote host: " host
ssh $user@$host "ls -l $path"
执行脚本时,我传入一个环境变量 $LAVAIP(在 .bashrc 中设置 - export LAVAIP="192.168.1.69"),它是远程服务器的 IP。下面的代码片段显示了发生了什么...
Specify path of directory to check: ~/bin
Specify remote user: lava
Specify remote host: $LAVAIP
ssh: Could not resolve hostname $lavaip: Name or service not known
这是怎么回事?它不明白主机名应该被解释为环境变量,并且它还尝试使用变量名的小写版本。
答案1
最可能的原因1您在消息中看到小写字母
ssh: Could not resolve hostname $lavaip: Name or service not known
作为FedKad 指出SSH 本身正在进行大小写转换,例如:
$ user=lava; host=\$LAVAIP
$ echo $host
$LAVAIP
但
$ ssh $user@$host
ssh: Could not resolve hostname $lavaip: Name or service not known
同时,它没有被扩展也是意料之中的——变量扩展不会发生在read
输入行上,一旦读取该值,它就变成了文字文本。例如
事实上,你可以做一些类似于那里接受的解决方案的事情,使用envsubst
:
$ export LAVAIP="192.168.1.69"
$ read -p "Specify remote user: " user
Specify remote user: lava
$ read -p "Specify remote host: " host
Specify remote host: $LAVAIP
$ echo "$(envsubst <<< "$user@$host")"
[email protected]
或者你可以使用变量间接引用:
# "unexport" the variable - doesn't need to be in the environment for this option
$ export -n LAVAIP
$ read -p "Specify remote user: " user
Specify remote user: lava
$ read -p "Specify remote host: " host
Specify remote host: LAVAIP
# note the lack of $ - just enter the variable's name
$ echo "$user@${!host}"
[email protected]
1但是,如果 plainecho $host
返回的是小写值,那么可以如果host
变量使用以下-l
属性声明,则会发生:
$ declare -l host
$ read -p "Specify remote host: " host
Specify remote host: $LAVAIP
$ echo $host
$lavaip
您可以使用以下方式检查declare -p
:
$ declare -p host
declare -l host="\$lavaip"