I have a server list in hostlist file and I am trying to execute below script:
我在主机列表文件中有一个服务器列表,我正在尝试执行以下脚本:
!/bin/bash
for server in cat hostlist; do ssh $server 'hostname ;id $(cat /etc/passwd | grep Luyang | awk -F '[:]' '{print $1}') ; id ppandey' >> b done
I want to fetch outputs for id command of user Luyang. For the same I have mentioned id $(cat /etc/passwd | grep Luyang | awk -F '[:]' '{print $1}')
but I am getting errors while running the script. I also tried to put '\' in front of all special characters but no luck.
我想获取用户Luyang的id命令的输出。同样我提到了id $(cat / etc / passwd | grep Luyang | awk -F'[:]''{print $ 1}')但我在运行脚本时遇到错误。我也试着把'\'放在所有特殊字符面前,但没有运气。
2 个解决方案
#1
0
There are a number of problems here:
这里有很多问题:
- The first line needs a
#
to be a proper shebang line (i.e.#!/bin/bash
). -
for server in cat hostlist
will run the loop twice, once with $server set to "cat", then with it set to "hostlist". You want to executecat hostlist
as a command and use its output, i.e.for server in $(cat hostlist)
.对于cat hostlist中的服务器,将运行循环两次,一次将$ server设置为“cat”,然后将其设置为“hostlist”。您希望将cat hostlist作为命令执行并使用其输出,即$(cat hostlist)中的服务器。
Actually, depending on the exact format and content of the file,
while read -u3 server; do ... done 3<hostfile
might be better, but thefor
version is probably good enough here. (The differences are thatfor
breaks the file into words, not lines, and expands any wildcards as if they were filenames. I wouldn't expect either to matter here.)实际上,取决于文件的确切格式和内容,同时读取-u3服务器;做...完成3
可能会更好,但for版本可能已经足够好了。> - You can't nest quotes the way you're trying to. When you have a single-quoted string like
'hostname ;id ... ; id ppandey'
, any single-quotes in the middle are taken as ending the single-quoted string, not as part of it. I'd switch to using double-quotes for the outer set, and then escaping the$
s inside to keep them from being interpreted. -
cat|grep|awk
is overcomplicated, sinceawk
can read directly from files and search all by itself. Just useawk -F : '/Luyang/ {print $1}' /etc/passwd
. - You need a semicolon or line break before
done
. Personally, I think breaking loops into logical lines makes them easier to read, so I'd go with that. - Finally, you might want to use absolute paths for the files hostlist and b. As it is, it'll look in the working directory of whatever process launched the script, which could be anything. You should not assume it's the directory the script is in.
第一行需要#是一个合适的shebang行(即#!/ bin / bash)。
你不能按照你想要的方式嵌套引号。当你有一个单引号的字符串,如'hostname; id ...; id ppandey',中间的任何单引号都被视为单引号字符串的结尾,而不是它的一部分。我将切换到使用双引号作为外部集合,然后转义$ s内部以防止它们被解释。
cat | grep | awk过于复杂,因为awk可以直接从文件中读取并自行搜索。只需使用awk -F:'/ Luyang / {print $ 1}'/ etc / passwd。
在完成之前,您需要分号或换行符。就个人而言,我认为将循环转换为逻辑行会使它们更容易阅读,所以我会选择它。
最后,您可能希望使用文件主机列表和b的绝对路径。实际上,它会查看启动脚本的任何进程的工作目录,这可能是任何事情。你不应该假设它是脚本所在的目录。
Here's what I get overall (except for absolute paths). Note that I also double-quoted "$server"
, just on general principles.
这是我得到的整体(绝对路径除外)。请注意,我还引用了“$ server”,只是基于一般原则。
#!/bin/bash
for server in $(cat hostlist); do
ssh "$server" "hostname; id \$(awk -F : '/Luyang/ {print \$1}' /etc/passwd); id ppandey" >> b
done
#2
-2
Just enclose your cat command between $() and ; after the append command.
只需将你的cat命令放在$()和;之间;在append命令之后。
!/bin/bash
for server in $(cat hostlist); do ssh $server 'hostname ;id $(cat /etc/passwd | grep Luyang | awk -F '[:]' '{print $1}') ; id ppandey' >> b; done
#1
0
There are a number of problems here:
这里有很多问题:
- The first line needs a
#
to be a proper shebang line (i.e.#!/bin/bash
). -
for server in cat hostlist
will run the loop twice, once with $server set to "cat", then with it set to "hostlist". You want to executecat hostlist
as a command and use its output, i.e.for server in $(cat hostlist)
.对于cat hostlist中的服务器,将运行循环两次,一次将$ server设置为“cat”,然后将其设置为“hostlist”。您希望将cat hostlist作为命令执行并使用其输出,即$(cat hostlist)中的服务器。
Actually, depending on the exact format and content of the file,
while read -u3 server; do ... done 3<hostfile
might be better, but thefor
version is probably good enough here. (The differences are thatfor
breaks the file into words, not lines, and expands any wildcards as if they were filenames. I wouldn't expect either to matter here.)实际上,取决于文件的确切格式和内容,同时读取-u3服务器;做...完成3
可能会更好,但for版本可能已经足够好了。> - You can't nest quotes the way you're trying to. When you have a single-quoted string like
'hostname ;id ... ; id ppandey'
, any single-quotes in the middle are taken as ending the single-quoted string, not as part of it. I'd switch to using double-quotes for the outer set, and then escaping the$
s inside to keep them from being interpreted. -
cat|grep|awk
is overcomplicated, sinceawk
can read directly from files and search all by itself. Just useawk -F : '/Luyang/ {print $1}' /etc/passwd
. - You need a semicolon or line break before
done
. Personally, I think breaking loops into logical lines makes them easier to read, so I'd go with that. - Finally, you might want to use absolute paths for the files hostlist and b. As it is, it'll look in the working directory of whatever process launched the script, which could be anything. You should not assume it's the directory the script is in.
第一行需要#是一个合适的shebang行(即#!/ bin / bash)。
你不能按照你想要的方式嵌套引号。当你有一个单引号的字符串,如'hostname; id ...; id ppandey',中间的任何单引号都被视为单引号字符串的结尾,而不是它的一部分。我将切换到使用双引号作为外部集合,然后转义$ s内部以防止它们被解释。
cat | grep | awk过于复杂,因为awk可以直接从文件中读取并自行搜索。只需使用awk -F:'/ Luyang / {print $ 1}'/ etc / passwd。
在完成之前,您需要分号或换行符。就个人而言,我认为将循环转换为逻辑行会使它们更容易阅读,所以我会选择它。
最后,您可能希望使用文件主机列表和b的绝对路径。实际上,它会查看启动脚本的任何进程的工作目录,这可能是任何事情。你不应该假设它是脚本所在的目录。
Here's what I get overall (except for absolute paths). Note that I also double-quoted "$server"
, just on general principles.
这是我得到的整体(绝对路径除外)。请注意,我还引用了“$ server”,只是基于一般原则。
#!/bin/bash
for server in $(cat hostlist); do
ssh "$server" "hostname; id \$(awk -F : '/Luyang/ {print \$1}' /etc/passwd); id ppandey" >> b
done
#2
-2
Just enclose your cat command between $() and ; after the append command.
只需将你的cat命令放在$()和;之间;在append命令之后。
!/bin/bash
for server in $(cat hostlist); do ssh $server 'hostname ;id $(cat /etc/passwd | grep Luyang | awk -F '[:]' '{print $1}') ; id ppandey' >> b; done