ssh one shot command gives partial results - ssh

I execute a command to grep a long log file on a remote server and the problem is whenever I ssh first and then execute the grep command remotely I get way more matches than if I do it in one shot as follows:
ssh host 'less file | grep something'
I was suspecting some default automatic timeout with the second version so I experimented with those options -o ServerAliveInterval=<seconds> -o ServerAliveCountMax=<int> but to no avail. Any idea what could be the problem?

The problem was related to less. It does not behave well outside of interactive mode. Using cat solved the issue.

Related

How do I kill a hanging TestCafe process using :::57664

I'm using TestCafe to test an app I'm working on. Today, when I went to run a TC test, I got the following message:
Error: listen EADDRINUSE: address already in use :::57664
I can usually handle these pretty easily: I issue the command:
lsof -i -P | grep -i "listen"
or
lsof -i tcp:57664
and then kill the offending task that is identified.
However, in this case, that port number isn't listed so I don't know which task to kill. also,
ps aux | grep -i "TestCafe"
doesn't show anything helpful.
Any suggestions on how to identify the hung task and kill it?

SED command to delete last line in a remote host

I have the following running one liner to delete last injected ED key from last line of authorized keys folder of a remote host.
sed -i '${/^\(ssh-ed25519\) \(.*\) \([A-Za-z][A-Za-z]*\.[A-Za-z][A-Za-z]*#hpe\.com\)$/d;}' .ssh/authorized_keys
I do a couple of operations after creating ED key and injecting it into remote host. Then I want to clear up as tear down step. However when I tried to run it by connecting to remote host it failed. I tried the following things:
ssh -T 'sh -c "sed command here"' # too many single and double quotes, so I gave up
Then I tried removing T terminal and as well as "sh -c" command running part
ssh root#my_remote_host "sed -i '${/^\(ssh-ed25519\) \(.*\) \([A-Za-z][A-Za-z]*\.[A-Za-z][A-Za-z]*#hpe\.com\)$/d;}' .ssh/authorized_keys"
had this error:
sed: couldn't open temporary file .ssh/sedWC1YAQ: Read-only file system
I referred to this link but it also didn't help : Using SED in a ssh command on a remote node
I appreciate any help, and let me know if what I'm trying is a good way to apply.

Script Stops after doing SSH

When I am doing SSH to some machine inside the for loop it is doing the ssh but not able to execute further.
Code is like:
string=c01.test.cloud.com,c02.test.cloud.com
for i in $(echo $string | sed "s/,/ /g")
do
ssh -t -t AppAccount#$i
cd a/b/c
str2=x,y,z
done
I take it from your question that you expect cd a/b/c to run on a remote server? That's not what this script is doing. The call to ssh opens an SSH tunnel, and provides you an interactive terminal connection. It then waits for that connection to terminate. (I suspect if you pressed Control-D, the script would continue.) Your use of -t -t here is particularly strange. Why do you want to force a remote pty? This is making the problem worse (not that much, since it won't work anyway, but this seems the opposite of what you'd want).
I think this is the script you meant:
string=c01.test.cloud.com,c02.test.cloud.com
for i in $(echo $string | sed "s/,/ /g")
do
ssh AppAccount#$i 'cd a/b/c; str2=x,y,z'
done
(This won't do anything of course, but I assume your real script has more to it than setting a shell variable and exiting.) The point is that you ned to pass the script you want to run as a parameter to ssh. Otherwise it's going to spawn an interactive shell and wait for you to close it.
Note that if your script is very complicated, it can be very inconvenient to stick it all in a single-quoted string. If your internal script is in its own file, a simple way to handle this is with bash -s which reads a script from stdin:
cat some_script | ssh server 'bash -s'
You can also use bash Here docs to achieve the same thing, but that is likely getting too fancy for this use.

running command on remote machine using ssh

i want to run some command on several machine using ssh. I know it can be done by just using the command "ssh user#hostname command". However, the command i want to run print some string on the console. Is there any way that send all the strings back to the console that i'm on?
You could run the commands in a screen:
screen -S test
ssh user#hostname command1
ssh user#hostname2 command2
You can then detach (Ctrl-D) from the screen, let it run for however long it will run, then re-attach (screen -r test) to the screen and see all of the output. This assumes that you won't have a ton of output from the commands, however. Here's a link to a tutorial on screen.
ssh user#hostname command
Does just that. if 'command' outputs something, it'll show on the terminal you ran ssh from.
Try e.g. ssh user#hostname ls -l
But as others have said, GNU screen is invaluable for this type of work.
You probably want to use Gnu Screen for this. You can start a process in a "virtual" terminal, "detach" the terminal and log out for however long you want... Then you can ssh back in and re-attach the terminal to see the console output.
Also have a look at nohup, for example:
ssh user#domain.com nohup script_that_outputs_strings.py > the_strings.txt
Then if you want to go back and monitor the progress, you could check back and tail the file or scp the output back to your local machine.
Why don't you send you an email back?
Or use a log file, and scp it to your current computer?
otherwise, I don't know!

How do I execute a command every time after ssh'ing from one machine to another?

How do I execute a command every time after ssh'ing from one machine to another?
e.g
ssh mymachine
stty erase ^H
I'd rather just have "stty erase ^H" execute every time after my ssh connection completes.
This command can't simply go into my .zshrc file. i.e. for local sessions, I can't run the command (it screws up my keybindings). But I need it run for my remote sessions.
Put the commands in ~/.ssh/rc
You can put something like this into your shell's startup file:
if [ -n "$SSH_CONNECTION" ]
then
stty erase ^H
end
The -n test will determine if SSH_CONNECTION is set which happens only when logged in via SSH.
If you're logging into a *nix box with a shell, why not put it in your shell startup?
.bashrc or .profile in most cases.
Assuming a linux target, put it in your .profile
Try adding the command below the end of your ~/.bashrc. It should be exited upon logoff. Do you want this command only executed when logging off a ssh session? What about local sessions, etc?
trap 'stty erase ^H; exit 0' 0
You probably could setup a .logout file from /etc/profile using this same pattern as well.
An answer for us, screen/byobu users:
The geocar's solution will not work as screen will complain that "Must be connected to a terminal.". (This is probably caused by the fact that .ssh/rc is processed before shell is started. See LOGIN PROCESS section from man 8 sshd).
Robert's solution is better here but since screen and byobu open it's own bash instance, we need to avoid infinite recursion. So here is adjusted byobu-friendly version:
## RUN BYOBU IF SSH'D ##
## '''''''''''''''''' ##
# (but only if this is a login shell)
if shopt -q login_shell
then
if [ -n "$SSH_CONNECTION" ]
then
byobu
exit
fi
fi
Note that I also added exit after byobu, since IMO if you use byobu in the first place, you normally don't want to do anything outside of it.