Nec*_*der 4 shell bash ssh awk shell-script
我有两个正在尝试的远程服务器ssh和cat一些文件..我想将 ssh 的输出输入到awk命令中。
这就是我所拥有的
\n\nssh username@host1 \xe2\x80\x9ccat /tmp/test/*\xe2\x80\x9d ssh username@host2 \xe2\x80\x9ccat /tmp/test/*\xe2\x80\x9d | awk \xe2\x80\x98 command \xe2\x80\x98\nRun Code Online (Sandbox Code Playgroud)\n但这不起作用,如果host2目录为空,则输出host1会重复两次。
我在这里做错了什么?
\n请注意某些 Windows 文本编辑器会使用的弯引号(\xe2\x80\x9c和\xe2\x80\x9d),请改用直引号 (\'或")。您还应该使用\'s,除非您有某种原因使用"s,例如让变量扩展,请参阅https://mywiki.wooledge.org/Quotes。
如果你想要一个 awk 管道,你应该这样做:
\n{ ssh username@host1 \'cat /tmp/test/*\'; ssh username@host2 \'cat /tmp/test/*\'; } | awk \' command \'\nRun Code Online (Sandbox Code Playgroud)\n但请考虑这样做,以便 awk 可以区分输入来自哪个命令,以防将来需要这种区分:
\nawk \' command \' <(ssh username@host1 \'cat /tmp/test/*\') <(ssh username@host2 \'cat /tmp/test/*\')\nRun Code Online (Sandbox Code Playgroud)\n区别如下:
\n$ seq 3 > file1\n$ seq 2 > file2\nRun Code Online (Sandbox Code Playgroud)\n错误的输出(因为FILENAME总是包含-且ARGV[1..2]为空):
$ { cat file1; cat file2; } | awk \'\n FILENAME == ARGV[1] { host="host1" }\n FILENAME == ARGV[2] { host="host2" }\n { print host, $0 }\n\'\n 1\n 2\n 3\n 1\n 2\nRun Code Online (Sandbox Code Playgroud)\n错误的输出(因为FILENAME和ARGV[1]包含相同的临时文件描述符但ARGV[2]为空):
$ awk \'\n FILENAME == ARGV[1] { host="host1" }\n FILENAME == ARGV[2] { host="host2" }\n { print host, $0 }\n\' <(cat file1; cat file2)\nhost1 1\nhost1 2\nhost1 3\nhost1 1\nhost1 2\nRun Code Online (Sandbox Code Playgroud)\n正确输出:
\n$ awk \'\n FILENAME == ARGV[1] { host="host1" }\n FILENAME == ARGV[2] { host="host2" }\n { print host, $0 }\n\' <(cat file1) <(cat file2)\nhost1 1\nhost1 2\nhost1 3\nhost2 1\nhost2 2\nRun Code Online (Sandbox Code Playgroud)\n通过这种提供输入的方法获得正确输出的其他可能方法:
\n$ awk \'{print host, $0}\' host=\'host1\' <(cat file1) host=\'host2\' <(cat file2)\nhost1 1\nhost1 2\nhost1 3\nhost2 1\nhost2 2\nRun Code Online (Sandbox Code Playgroud)\n
您需要对命令进行分组。最简单的方法是使用花括号将它们分组而不创建子 shell:
{ ssh username@host1 'cat /tmp/test/*'; ssh username@host2 'cat /tmp/test/*'; } |
awk ' command '
Run Code Online (Sandbox Code Playgroud)
您还可以使用括号,但这有点不优雅,因为它创建了一个您不需要的子 shell。但是,最终结果是相同的,在这种情况下确实不应该产生任何影响。另外,您不需要;像使用时那样添加结尾{ }:
( ssh username@host1 'cat /tmp/test/*'; ssh username@host2 'cat /tmp/test/*' ) |
awk ' command '
Run Code Online (Sandbox Code Playgroud)
您看到重复输出的原因是因为这两个cat命令都在同一主机上运行。localhost检查用作两个命令的主机时以及运行后的输出set -x:
$ ls /tmp/test
file1
$ ssh localhost "cat /tmp/test/*" ssh localhost "cat /tmp/test/*"
+ ssh localhost 'cat /tmp/test/*' ssh localhost 'cat /tmp/test/*'
/tmp/test/file1
/tmp/test/file1
cat: ssh: Is a directory
cat: localhost: No such file or directory
cat: cat: No such file or directory
Run Code Online (Sandbox Code Playgroud)
正如您在上面看到的,这被解释为“ssh localhost cat arg1 arg2 arg3 arg4”,因此cat运行在localhost(host1在您的情况下),并作为参数给出/tmp/test/*,,ssh(localhost在host2您的情况下),cat然后/tmp/test/*再次。所以 host1 的内容/tmp/test被catted 两次。
| 归档时间: |
|
| 查看次数: |
516 次 |
| 最近记录: |