【问题标题】:Sending commands to screen: limits of "stuff", quirks w/ newlines向屏幕发送命令:“东西”的限制,带有换行符的怪癖
【发布时间】:2021-06-03 17:43:20
【问题描述】:

试图通过“stuff”选项将长命令字符串传递给 Screen。当字符串很短并且存在于 bash 中时,已经在许多脚本中成功完成此操作,如下所示:

screen -d -m -S worker
screen -S worker -X -p 0 stuff $'/usr/bin/env python3 /root/worker.py\n'

在这种情况下,我正在从文件中读取命令。我可以将 '\n' 附加到该文件,但 $ () 构造函数会吃掉换行符。我尝试了 printf、ISF= 和许多排列,但是在我可以保留换行符的地方,不知何故该命令无法进入屏幕。

GEO_COMMAND=/foo/geo_command.txt
screen -S worker -X -p 0 stuff printf '%\n' "$GEO_COMMAND"
or
screen -S worker -X -p 0 stuff $GEO_COMMAND

GEO_COMMAND: ''foo -bar -geo1 -geo2 -blah -keys ..... 160 个字符后 ...; /root/finish_job.sh\n '

答案在下面突出显示,为后代添加:

screen 'stuff' 选项不喜欢大型命令,并且对换行非常特别。

下面的评论/答案解决了可靠的换行问题,但要粘贴/执行大命令,答案是使用“readreg”通过命令读取文本文件,然后使用第二个命令“粘贴”将其传递到屏幕',如下所示。

这种方法不需要尾随换行符,不需要您将命令(在文件中)用引号括起来,并且也将接受传导命令 (; /foo/bar/sh)。

【问题讨论】:

  • 您可以简单地通过并置字符串来连接它们;每个字符串都可以使用不同的引用风格。例如,screen ... "$GEO_COMMAND"$'\n'
  • 请把它放在问题中。
  • 类似于GEO_COMMAND="..."$'\n'。您实际上并没有在值中添加换行符,只是一个由反斜杠和 n 组成的有向图。
  • 已添加 - 对此感到抱歉。串联有助于可靠地添加换行符以执行命令。奇怪的是,该命令现在还导致 bash 在屏幕上抛出错误:没有这样的文件或目录。如果我复制/粘贴相同的命令,它会在该屏幕中执行而没有错误 = 对我来说没有意义
  • 你能解释一下GEO_COMMAND = /foo/geo_command.txt吗?随着= 周围的空格,bash 将寻找一个名为 GEO_COMMAND 的命令,因此GEO_COMMAND=/foo/geo_command.txt 可能会更好。但是,我认为您想要添加文件的内容,我认为您想要GEO_COMMAND=$(cat /foo/geo_command.txt) 或没有附加变量screen -S worker -X -p 0 stuff $(cat /foo/geo_command.txt)

标签: bash sh gnu-screen


【解决方案1】:

screen 手册页建议 stuff 不应用于大字符串。作为替代方案,您可以将文件读入寄存器(一种缓冲区),然后将其粘贴。这里p是任意寄存器:

screen -S worker -X readreg p /foo/geo_command.txt
screen -S worker -X paste p

这种更直接的方法的优点是您不需要通过中间 shell 变量,如 GEO_COMMAND="$(cat ...)",它会丢失最后的换行符。此外,screen 不会解释数据(例如,文件中的 2 个字符 \n 不会被 1 个字符的换行符替换)。

【讨论】:

  • 繁荣 - 就像一个魅力。男人说:'你不能用“东西”命令粘贴大缓冲区......'但从不定义大!这行得通。您能否以三种方式为后代编辑上面的命令:(1)请将它们设为“屏幕 -S 绘图仪 -X ....”,这是惯例,(2)请注意,这不需要在前面的任何步骤中将我的 GEO_COMMAND 读入 bash,并且 (3) 这绝对不需要使用换行符的技巧来工作——将执行一个没有尾随换行符的 .txt 文件。谢谢!
【解决方案2】:

正如您已经发现的那样,$(cmd) 会从cmd 的输出中删除尾随换行符,并且无法阻止这种行为。

但是,您可以在 $() 之后使用尾随换行符。

screen -S worker -X -p 0 stuff "$(cat yourFile)"$'\n'

但是,这可能会出现意外行为,因为 screen stuff 在将它们输入会话之前会解释 ^C\n 等控制序列。因此,假设文件名本身不包含任何特殊符号,则获取脚本文件可能更明智:

screen -S worker -X -p 0 stuff '. yourFile\n'

【讨论】:

  • 这有帮助,正如上面 chepner 的评论:它可靠地添加了换行符。我已经尝试过他的格式(确切地说,如下)和你的格式(正如你输入的那样)。这两种情况都会导致绘图仪抛出“没有这样的文件或目录”的抱怨,这是不可信的,因为在屏幕 works 中复制/粘贴/输入相同的命令。我在想有什么东西不见了.. GEO_COMMAND=$(
  • 我不认为这是这种方法的问题,而是文件中的命令的问题。请尝试找出哪个命令产生错误消息(set -x 可能有帮助)。一旦发现有问题的命令并且无法自行修复,请打开一个新问题。
  • @ToddCurry 另一方面,我刚刚发现screen stuff 可以解释像^C\n(文字字符串)这样的控制序列。也许这导致了你的错误。我用解决方法编辑了答案。通常我会写一个引用机制,但我找不到screen stuff 解释的描述,所以这将是一个疯狂的猜谜游戏。
  • Socowi,问题似乎是该命令太大而无法传递到屏幕,并且很可能被修改了。非常感谢您的建议!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-29
  • 2021-08-28
  • 2021-04-11
  • 1970-01-01
  • 2014-11-23
  • 2015-08-30
相关资源
最近更新 更多