带有EOF的SSH可以正确设置$ PATH,但是为什么没有EOF却不能正常工作?

时间:2019-04-18 23:20:53

标签: oracle unix ksh

我想了解为什么ssh不会将$ PATH设置为.profile中确定的任何值,但是当ssh使用EOF时似乎会这样做。

我想在脚本中运行此行:

DIR_EXPANDED=`ssh $TOADDRESS "$(typeset -f get_dir); get_dir $DIR $DBNAME"`

get_dir的定义如下:

function get_dir() {
  DIRECTORY_NAME=$1
  DBNAME=$2

  if [ -z "$DIRECTORY_NAME" ]; then
    echo "Enter Directory Name:"; read DIRECTORY_NAME
  elif [ -n "$2" ]; then
    . oraenv $DBNAME
  fi
  DIRECTORY=`sqlplus -s '/ as sysdba' << EOF
  set pages 0 head off feed off

  select directory_path from all_directories where directory_name='$DIRECTORY_NAME';

EOF`

  echo $DIRECTORY;
}

但是,运行脚本会导致错误

ksh[10]: .: oraenv: cannot open [No such file or directory]

我发现这是因为ssh'ing时路径设置不正确,如下所示:

ssh $TOADDRESS 'echo $PATH'
/usr/local/bin:/usr/bin

通过反复试验,我发现这可行:

TODIR_EXPANDED=`ssh $TOADDRESS << EOF
  $(typeset -f get_dir); get_dir $TODIR $TODBNAME
EOF`

有人可以解释ssh为什么这样工作吗?以及如何/是否有可能使用我首先描述的单线?

1 个答案:

答案 0 :(得分:1)

如果您使用ssh HOST command,则会加载非交互式外壳,该外壳不会读取.profile的登录外壳或.kshrc的交互式外壳。

如果您使用ssh HOST,它将启动一个交互式shell(尽管未分配伪TTY)并读取.kshrc(或类似情况,具体取决于生成的实际shell),然后继续从中读取命令标准输入。

因此,如果您希望使这些功能可用,可以这样做:

DIR_EXPANDED=$(ssh $TOADDRESS ". ./.kshrc; $(typeset -f get_dir); get_dir $DIR $DBNAME")

(我还将不推荐使用的命令替换形式(使用重音符号)更改为现代/ POSIX形式,因为这可以修复一些错误。)