0

I have a list of servers in a file I'll call "boxes."

I'm running the following:

bastion:~ # while read i j; do ssh -n $i 'echo $(hostname)'; done < boxes

When I run this, I should be getting the host name of every box I'm supposedly SSHing into right? But what I'm getting is my hostname "bastion" over and over as if the command is not SSHing to any box.

Any idea why that might be or what I'm doing wrong here?

Thanks.

EDIT: I couldn't get SSH to work for this task. In the end I swapped the ssh for ansible -m shell.

Mike
  • 71
  • 1
  • 9
  • Sure your real code is using single quotes as shown here? Changing from `'echo $(hostname)'` to just `hostname` would moot that failure mode and also make your script a tiny bit faster. – Charles Duffy Mar 28 '22 at 20:56
  • Well this isn't the full command I'm running -- The boxes file has two columns in it. What I'm actually doing is: ssh $i ' echo $i: $(lsof | grep $j | wc -l) ', but it just prints 0 for every host it "connects" to. I got suspicious so I changed it to hostname just to check and it looks to me like it's connecting to anything. – Mike Mar 28 '22 at 20:58
  • 2
    @Mike The single-quotes prevent `$i` and `$j` from being expanded until they reach the remote system... where they aren't defined (they're only defined in the *local* shell). – Gordon Davisson Mar 28 '22 at 21:19
  • @Barmar, I thought this was a duplicate of that myself, closed it reflexively, and then reopened it once I took a closer look. The OP's use of `ssh -n` prevents it from eating stdin. – Charles Duffy Mar 28 '22 at 22:28
  • @CharlesDuffy Great minds jump to conclusions alike. And not only that, but this isn't even the normal symptom of that bug, since he's getting the same output multiple times, not a single iteration. – Barmar Mar 28 '22 at 22:32
  • _nod_. Honestly, this smells to me a _lot_ like the OP's real test case isn't a precise match for the code in their question. – Charles Duffy Mar 28 '22 at 22:34
  • @Mike, could you please add the trace logs emitted from running `bash -x yourscript` to the question? – Charles Duffy Mar 28 '22 at 22:35
  • @Mike, ...consider the following, which uses `printf %q` to make `eval`-safe versions of your variables: `printf -v i_q '%q' "$i"; printf -v j_q '%q' "$j"; ssh "$i" "echo $i_q: \$(lsof | grep $j_q | wc -l)"`. I wouldn't ever actually do that in real-world production code -- I always use function encapsulation for code I'm going to pass over ssh -- but there are other Q&A entries where the techniques to make it maintainable are presented. – Charles Duffy Mar 28 '22 at 22:44
  • @Mike, ...see [How to have simple and double quotes in a scripted ssh command](https://stackoverflow.com/questions/45308395/how-to-have-simple-and-double-quotes-in-a-scripted-ssh-command) re: the above-referenced "making it maintainable". – Charles Duffy Mar 28 '22 at 22:46
  • ...in this case, that might look like: `remote_code() { echo "$1: $(lsof | grep "$2" | wc -l)"; }; while read i j; do ssh -n "$i" "$(declare -p i j); $(declare -f remote_code);"' remote_code "$i" "$j"'; done – Charles Duffy Mar 28 '22 at 22:48
  • `echo $hostname` could be just `$hostname`. What is the content of file "boxes"? – Nic3500 Mar 28 '22 at 23:07
  • @Nic3500, the `$` is wrong there, it should just be `hostname`, not `$hostname`. And as the OP says, `boxes` is a file with two columns, the first of which is the name of the host to check, and the second of which is a parameter for the test they want to run. – Charles Duffy Mar 29 '22 at 12:05
  • @Mike, ...if you don't intend to follow up in helping us run this down so we can build an answer that's useful to other people, I'd suggest deleting the question. I'd be disappointed if you did that, though -- if you answered the follow-up questions asked above (particularly the request for xtrace logs) and were otherwise willing to stick through the process I'm quite sure we could figure it out. ansible isn't magic -- it doesn't do anything you can't do from the command line. – Charles Duffy Mar 29 '22 at 18:14

1 Answers1

0

hostname is enough

my favorite solution with GNU Parallel (much faster) sudo apt-get install parallel

 parallel --nonall --slf boxes hostname

you can add --tag and much more https://www.gnu.org/software/parallel/parallel_tutorial.html

lojza
  • 1,823
  • 2
  • 13
  • 23
  • This is all true, but (1) the OP's real code is more complicated, as they discuss in comments; and (2) can you account for why they were seeing the problem in the first place? – Charles Duffy Mar 29 '22 at 12:03