copy/pasting bash 使用 heredocs 命令进入终端时的奇怪行为
Strange behaviour when copy/pasting bash commands with heredocs into terminal
为了简化某些流程,我记录了大量终端命令,以便在需要时复制和粘贴它们。
然而,我遇到了一些奇怪的行为,如下所示:
ssh $USER@$SERVER 'rm ~/backup.tar'
tar -xvzf backup.tar
cd backup
当我复制所有这些并将其粘贴到终端时,SSH 命令被执行,导致它在运行时暂停。完成后,tar
和 cd
命令不会执行 - 就好像它们从未被复制过一样。
我猜这是因为当 SSH 命令仍在执行时,它们以某种方式 "typed"(我知道这不是正确的词),因此被该命令消耗 - 在那里什么都不做。
当然,这是有道理的,但这里有点奇怪:
ssh $USER@$SERVER 'rm ~/backup.tar' <<EOF
EOF
tar -xvzf backup.tar
cd backup
这似乎是同一件事,但带有一些随机的、无目的的 heredoc。但是,当我到达那里时,tar
和 cd
命令已成功粘贴并在 SSH 命令完成后执行。
所以我的问题是:
heredoc 有什么不同导致 tar
和 cd
像我最初预期的那样被粘贴?
有没有比随机攻击 heredoc 来获得相同结果更好的方法?
ssh
读取标准输入。如果您提供 HERE 文档,它会从中获取输入,因此不会使用命令读取真正的标准输入。
在第一个示例中,tar
和 cd
命令转到 ssh 的标准输入。在第二个中,ssh 的标准输入被终止,因此 bash 执行 tar
和 cd
当你运行一个命令正常时,进程的标准输入连接到终端。终端程序接收到的任何字符都会传递给进程。但是当你 运行 一个带有重定向的命令时,就像你使用的 heredoc 一样,进程的标准输入连接到一个包含 heredoc 内容的内存缓冲区。在这种情况下,终端程序接收到的字符不会传递给进程;相反,它们会被保存,在该过程完成后,终端程序会确定如何处理它们。
至于如何修复:最好的方法可能是使用 shell 脚本,而不是复制和粘贴。但如果由于某种原因你不能这样做,重定向似乎是一个合理的解决方案。您可以 运行
而不是提供 heredoc
ssh $USER@$SERVER 'rm ~/backup.tar' </dev/null
为了简化某些流程,我记录了大量终端命令,以便在需要时复制和粘贴它们。
然而,我遇到了一些奇怪的行为,如下所示:
ssh $USER@$SERVER 'rm ~/backup.tar'
tar -xvzf backup.tar
cd backup
当我复制所有这些并将其粘贴到终端时,SSH 命令被执行,导致它在运行时暂停。完成后,tar
和 cd
命令不会执行 - 就好像它们从未被复制过一样。
我猜这是因为当 SSH 命令仍在执行时,它们以某种方式 "typed"(我知道这不是正确的词),因此被该命令消耗 - 在那里什么都不做。
当然,这是有道理的,但这里有点奇怪:
ssh $USER@$SERVER 'rm ~/backup.tar' <<EOF
EOF
tar -xvzf backup.tar
cd backup
这似乎是同一件事,但带有一些随机的、无目的的 heredoc。但是,当我到达那里时,tar
和 cd
命令已成功粘贴并在 SSH 命令完成后执行。
所以我的问题是:
heredoc 有什么不同导致 tar
和 cd
像我最初预期的那样被粘贴?
有没有比随机攻击 heredoc 来获得相同结果更好的方法?
ssh
读取标准输入。如果您提供 HERE 文档,它会从中获取输入,因此不会使用命令读取真正的标准输入。
在第一个示例中,tar
和 cd
命令转到 ssh 的标准输入。在第二个中,ssh 的标准输入被终止,因此 bash 执行 tar
和 cd
当你运行一个命令正常时,进程的标准输入连接到终端。终端程序接收到的任何字符都会传递给进程。但是当你 运行 一个带有重定向的命令时,就像你使用的 heredoc 一样,进程的标准输入连接到一个包含 heredoc 内容的内存缓冲区。在这种情况下,终端程序接收到的字符不会传递给进程;相反,它们会被保存,在该过程完成后,终端程序会确定如何处理它们。
至于如何修复:最好的方法可能是使用 shell 脚本,而不是复制和粘贴。但如果由于某种原因你不能这样做,重定向似乎是一个合理的解决方案。您可以 运行
而不是提供 heredocssh $USER@$SERVER 'rm ~/backup.tar' </dev/null