简体   繁体   中英

Syntax Error The source line is 1

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.

There are a number of problems here:

  • The first line needs a # to be a proper shebang line (ie #!/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 execute cat hostlist as a command and use its output, ie for server in $(cat hostlist) .

    Actually, depending on the exact format and content of the file, while read -u3 server; do ... done 3<hostfile while read -u3 server; do ... done 3<hostfile might be better, but the for version is probably good enough here. (The differences are that for breaks the file into words, not lines, and expands any wildcards as if they were filenames. I wouldn't expect either to matter here.)

  • You can't nest quotes the way you're trying to. When you have a single-quoted string like 'hostname ;id ... ; id ppandey' '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, since awk can read directly from files and search all by itself. Just use awk -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.

Here's what I get overall (except for absolute paths). Note that I also double-quoted "$server" , just on general principles.

#!/bin/bash
for server in $(cat hostlist); do
    ssh "$server" "hostname; id \$(awk -F : '/Luyang/ {print \$1}' /etc/passwd); id ppandey" >> b
done

Just enclose your cat command between $() and ; after the append command.

!/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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM