Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell脚本SSH行为_Shell_Ssh - Fatal编程技术网

Shell脚本SSH行为

Shell脚本SSH行为,shell,ssh,Shell,Ssh,我开始编写shell脚本大约2天 目前我有以下代码 echo "Permission to Access to Remote Machine" ssh $USERNAME@$HOSTNAME "pg_dump -f /dbexport.sql -t tb1 -t tb2 -t tb3 dbname" echo "Permission to Access to Remote Machine to transfer data file" scp $USERNAME@$HOSTNAME:/dbexp

我开始编写shell脚本大约2天

目前我有以下代码

echo "Permission to Access to Remote Machine"
ssh $USERNAME@$HOSTNAME  "pg_dump -f /dbexport.sql -t tb1 -t tb2 -t tb3 dbname"
echo "Permission to Access to Remote Machine to transfer data file"
scp $USERNAME@$HOSTNAME:/dbexport.sql /export/bin/
echo "Permission to delete temporary file on remote machine"
ssh $USERNAME@$HOSTNAME  "rm /dbexport.sql"
echo "Creating Database..."
现在我有两个问题

1-是否有一个好方法一次性完成此操作?我现在要做三次。。。我不想使用其他第三方脚本,也不想使用RSA密钥进行ssh身份验证

2-是否有办法知道该命令是否出现故障


非常感谢您的第一个问题,我想不出一个好方法将这三个命令合并为一个如果它们都在远程机器上执行命令,您可以执行以下操作

ssh user@remote sh -c 'dothis ; dothat'
<>但是中间有一个<代码> SCP < /代码>。我会使用RSA或DSA密钥,但你说你不想这样做(为什么?)

对于第二个问题,
ssh
scp
命令都返回一个状态,指示它们是否成功。例如,这:

ssh user@remote /bin/false ; echo $?

应打印1,表示失败。(如果您正在使用csh或tcsh,请将
$?
更改为
$status
)阅读手册页(
man ssh
man scp
)并查找底部的“退出状态”部分。

要将数据库远程转储到本地文件,我会将其转储到stdout并在本地重定向,例如

ssh $USERNAME@$HOSTNAME "pg_dump -f /dev/stdout -t tb1 -t tb2 -t tb3 dbname" > /export/bin/dbexport.sql
在服务器上执行的命令行的返回码将作为ssh调用的返回码返回给您。如果ssh失败(例如连接问题),您将获得255。如果一切正常,你得到0

Bash在shell变量$?中为您提供最后执行的命令的返回代码?。您可以通过以下方式使用它:

ssh $USERNAME@$HOSTNAME "pg_dump -f /dev/stdout -t tb1 -t tb2 -t tb3 dbname" > /export/bin/dbexport.sql
err=$?
if [ $err -ne 0 ]; then
  echo "Dump failed with error code ${err}!"
fi
或者,如果您对确切值不感兴趣:

if ! ssh $USERNAME@$HOSTNAME "pg_dump -f /dev/stdout -t tb1 -t tb2 -t tb3 dbname" > /export/bin/dbexport.sql; then
  echo "Dump failed!"
fi
pg_dump
手册页可能会为您提供错误代码。从ssh手册页:

EXIT STATUS
     ssh exits with the exit status of the remote command or with 255 if an
     error occurred.

如果您绝对不想使用密钥(我不理解),有一种方法可以打开连接并随后使用它

您可以使用ssh选项
ControlMaster
ControlPath
:首先使用
ControlMaster=yes
建立连接,询问密码,并在您告诉的地方保留一个控制套接字,然后使用
ControlPath
。接下来,告诉您的ssh命令在
ControlMaster=no
的情况下使用此套接字

echo "Creating control socket"
ssh $USERNAME@$HOSTNAME -o ControlMaster=yes,ControlPath=whereveryouwant -Nf
echo "Permission to Access to Remote Machine"
ssh $USERNAME@$HOSTNAME -o ControlMaster=no,ControlPath=whereveryouwant "pg_dump -f /dbexport.sql -t tb1 -t tb2 -t tb3 dbname"
echo "Permission to Access to Remote Machine to transfer data file"
scp -o ControlMaster=no,ControlPath=whereveryouwant $USERNAME@$HOSTNAME:/dbexport.sql /export/bin/
echo "Permission to delete temporary file on remote machine"
ssh $USERNAME@$HOSTNAME -o ControlMaster=no,ControlPath=whereveryouwant "rm /dbexport.sql"
echo "Creating Database..."
但在这里,我不太确定如何在适当的时候摆脱这种可能存在安全风险的控制连接。也许您可以将
-Nf
替换为-f“sleep 30m”,具体取决于整个过程的持续时间

另一种选择是,如果远程标准输出上没有其他输出,则直接通过管道获取SQL转储,而不使用临时文件

ssh $USERNAME@$HOSTNAME "pg_dump -f - -t tb1 -t tb2 -t tb3 dbname"  > /export/bin/dbexport.sql

简短、整洁,没有潜在的干扰中间文件。(但我不确定
-f-
部分-也许有另一种方法可以告诉pg_dump将其内容输出到stdout。)

在不创建文件的情况下将远程服务器复制到本地计算机,使用管道

ssh-C{ssh.user}@{remote\u host}\'PGPASSWORD={remote\u dbpassword} pg|dump-U{remote|dbuser}{remote|dbname}bzip2-c'\\ bunzip2-dc |PGPASSWORD={local_dbpassword}psql-U{local_dbuser}{local_dbname}


第一行的引号不匹配。为什么不使用RSA密钥?(我想你的理由同样适用于DSA密钥。)这看起来很棒!你能提供更多关于ssh返回值的信息吗?如果由于任何原因失败,它将返回false。。。甚至是一个错误的密码?在上面的答案中添加了返回值信息。