终端将不会被分配,因为stdin不是终端
我正在尝试编写一个在远程服务器上创建一些目录的shell脚本,然后使用scp将文件从本地计算机复制到远程计算机上。 这是我迄今为止的:
ssh -t user@server<<EOT
DEP_ROOT='/home/matthewr/releases'
datestamp=$(date +%Y%m%d%H%M%S)
REL_DIR=$DEP_ROOT"/"$datestamp
if [ ! -d "$DEP_ROOT" ]; then
echo "creating the root directory"
mkdir $DEP_ROOT
fi
mkdir $REL_DIR
exit
EOT
scp ./dir1 user@server:$REL_DIR
scp ./dir2 user@server:$REL_DIR
每当我运行它时,我都会收到以下消息:
Pseudo-terminal will not be allocated because stdin is not a terminal.
剧本永远挂起。
我的公钥在服务器上是可信的,我可以在脚本之外运行所有的命令。 有任何想法吗?
尝试使用ssh -t -t (或简称ssh -tt )来强制伪tty分配,即使stdin不是终端。
另请参见:终止由bash脚本执行的SSH会话
从ssh手册页:
-T Disable pseudo-tty allocation.
-t Force pseudo-tty allocation. This can be used to execute arbitrary
screen-based programs on a remote machine, which can be very useful,
e.g. when implementing menu services. Multiple -t options force tty
allocation, even if ssh has no local tty.
还有手动选项-T
禁用伪tty分配
Per zanco的回答是,你没有提供远程命令给ssh ,因为shell解析命令行的方式。 要解决此问题,请更改ssh命令调用的语法,以便远程命令由语法正确的多行字符串组成。
有多种可以使用的语法。 例如,由于可以将命令传送到bash和sh ,也可能是其他shell,最简单的解决方案是将ssh shell调用与heredocs结合使用:
ssh user@server /bin/bash <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
请注意,执行上面没有/bin/bash将导致警告Pseudo-terminal will not be allocated because stdin is not a terminal 。 还要注意, EOT被单引号括起来,所以bash将heredoc识别为nowdoc,关闭局部变量插值,以便命令文本将原样传递给ssh 。
如果你是管道迷,你可以重写上面的内容,如下所示:
cat <<'EOT' | ssh user@server /bin/bash
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
关于/bin/bash警告适用于上述情况。
另一种有效的方法是将多行远程命令作为单个字符串传递,使用多层bash变量插值,如下所示:
ssh user@server "$( cat <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
)"
上述解决方案以下列方式解决了此问题:
ssh user@server被bash解析,并被解释为ssh命令,随后是一个参数user@server以传递给ssh命令
"开始一个插入的字符串,当完成时,它将包含一个参数传递给ssh命令,在这种情况下,它将被ssh解释为要作为user@server执行的远程命令
$(开始一个要执行的命令,输出被周围的内插字符串捕获
cat是一个输出任何文件内容的命令。 cat的输出将被传回到捕获的内插字符串中
<<开始一场狂欢heredoc
'EOT'指定heredoc的名称是EOT。 单引号'周围的EOT指定的定界符应被解析为一个nowdoc,这是定界符的一种特殊形式,其内容不要被bash的插值,但在文字格式,而传递
在<<'EOT'和<newline>EOT<newline>之间遇到的任何内容将被附加到nowdoc输出
EOT终止nowdoc,导致创建一个nowdoc临时文件并将其传递回调用cat命令。 cat输出nowdoc并将输出传递回捕获内插字符串
)结束要执行的命令
"结束捕获内插字符串,内插字符串的内容将作为单个命令行参数传递回ssh ,该ssh将解释为要作为user@server执行的远程命令
如果您需要避免使用cat类的外部工具,并且不介意使用两个语句而不是一个语句,请使用带有heredoc的内置read来生成SSH命令:
IFS='' read -r -d '' SSH_COMMAND <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
ssh user@server "${SSH_COMMAND}"
链接地址: http://www.djcxy.com/p/17501.html
上一篇: terminal will not be allocated because stdin is not a terminal
