Unix/Linux 通过 ssh 运行复杂命令

Unix/Linux 通过 ssh 运行复杂命令

我正在尝试通过 ssh 连接到服务器,然后找到今天的文件,然后在这些文件中执行 grep 操作。但我收到一个错误,find: missing argument to `-exec'.

我在这里缺少什么?

ssh server.name find /dir1/subdir/filelist* -maxdepth 1 type f -mtime 0 -exec grep 'pattern' {} \;

答案1

您的代码存在问题:

  1. 本地 shell 可以扩展/dir1/subdir/filelist*到一个或多个匹配路径。这些路径可能存在于远程端,也可能不存在。

  2. 本地ssh根据它获取的多个参数构建 shell 代码(在远程端运行)。论据是:

    • find
    • /dir1/subdir/filelist*(如果没有本地匹配)
    • -maxdepth
    • 1
    • -type(我假设你type是一个错字)
    • f
    • -mtime
    • 0
    • -exec
    • grep
    • pattern(因为本地 shell 用完了引号)
    • {}
    • ;(因为本地shell用掉了反斜杠)

    构建的shell命令是:

    find /dir1/subdir/filelist* -maxdepth 1 -type f -mtime 0 -exec grep pattern {} ;
    

    这不是一个有效的find命令,因为(远程)shell 将解释;为命令终止符,因此;永远不会到达find.另请注意,pattern在远程 shell 的上下文中, 未加引号。

我认为这正是您想要在远程端的 shell 中运行的命令:

find /dir1/subdir/filelist* -maxdepth 1 -type f -mtime 0 -exec grep 'pattern' {} \;

如何通过 ssh 执行复杂的命令行以及我的回答。我不会在这里重复所有内容。最重要的事情:

为了控制远程 shell 将获得的内容$command_line_built_by_ssh,您需要理解、预测和策划之前发生的解析和解释。您需要制作本地命令,所以本地 shell 并消化它,它就变成了您想要在远程端执行的ssh确切内容。$command_line…

ssh一个基本的解决方案是将精确的(远程)命令作为单个参数传递给本地。在您的情况下,本地命令可能是:

ssh server.name 'find /dir1/subdir/filelist* -maxdepth 1 -type f -mtime 0 -exec grep '\''pattern'\'' {} \;'

在我对相关问题的回答中,我讨论了更多的想法。

答案2

您没有使用此 ssh 命令运行多个命令,而只是运行一个更复杂的 find 命令。

这里有两个主要问题。

  • 根据您编写命令的方式,glob 模式将在客户端上进行评估。
  • 出现错误消息的原因是;未到达find命令。基本上,ssh连接参数并将它们传递到sh -c服务器上。你需要类似的东西\\\;

除非您在服务器上需要 stdin,否则最简单的解决方案是将 stdin 上的命令发送到 shell。这消除了对引号的需要。

ssh server.name /bin/sh <<'EOF'
find /dir1/subdir/filelist* -maxdepth 1 -type f -mtime 0 -exec grep 'pattern' {} \;
EOF

相关内容