SSH Command Execution Hangs, although interactive shell functions fine
The problem was indeed my login script, although not to do with requiring a terminal (I'd suspected that and tested with the -t
and -T
options). The problem was that my .bashrc
was running an exec
(in this case to zsh
- because our system doesn't allow chsh
to zsh
).
The offending line:
test -f /usr/bin/zsh && exec /usr/bin/zsh
Solved by first checking for interactive shell and exiting if so:
[ -z "$PS1" ] && return
test -f /usr/bin/zsh && exec /usr/bin/zsh
So, essentially, because the shell was execing into zsh
, ssh
was waiting for this to finish - which never happened.
I am a little confused why my .bashrc
was being called at all - I thought this was only for interactive shells, but the exact purpose and order of the various init scripts is something I don't think I'll ever learn.
I hope this can be useful to others who have some kind of exec
in their startup scripts.
BTW - the other two answers were on the right track so I was completely unsure if I should 'answer' or just comment their answers. If answering my own question is morally wrong on stackoverflow, let me know and I'll do penitence. Thank you to the other answerers.
Bash function doesn't work for remote ssh command execution although interactive shell function fine
Your title says it all, actually. When you do ssh login@remote 'my command'
, your shell is NOT interactive, by definition, since you provide a command. However, ~/.bashrc
is only sourced by bash
when you shell is interactive.
When you execute ssh login@remote 'my command'
, here is what happens:
- your machine connects first to "remote" with user "login"
- then
sshd
, the ssh server running on "remote", executes your shell with the parameters-c 'my command'
(i.e.bash -c 'my command'
since you are using bash) - since it is called with
-c
,bash
executes directly your command without reading your startup files
The solution? Source your startup file before executing your command:
ssh login@remote 'source ~/.bash_aliases; my command'
SSH remote command hangs only on my user
My problem Resolved !!! Thanks for @Aaron for helping me in debugging it.
I was going through this link and found that exec
line from login profile making such issue each time when I do ssh.
From .cshrc
file I removed the following line. That solved my problem.
exec bash
Thanks for everyone showing interest to solve this issue.
ssh exec a simple command cost a few seconds
One thing that you could try is to run SSH in verbose mode and see at which stage it wastes the most time.
ssh -vvv root@10.17.1.155 'echo "hello,world!"'
And then based on your findings adopt your ssh config file to exclude slow cipher suites and other CPU intensive things. Some tips about that here.
However, you will not be able to achieve close to real-time performance over ssh if you establish a new connection every time. You could put your script/command into a loop and set seep value to 1s.
ssh root@10.17.1.155 'while true; do echo "Hello, world!"; sleep 1s; done'
But I would use something that is designed for such application like SNMP protocol. Here is an example configuration:
https://www.incredigeek.com/home/snmp-and-shell-script/
Get ssh remote command to terminate so that xargs with parallel option can continue
Instead of the remote command being
startServer; sleep 5; grep -m 1 "server up" <(tail -f log)
I'd use
grep -m 1 "server up" <(tail -F log -n 0) & startServer ; wait
Differences:
- Start tailing the log before attempting to restart the server, so that we don't miss any messages. We start at the end of the log so we don't see any previous "server up" messages.
- Use
tail
's-F
option instead of-f
, so that if the log file is rotated we will follow the new file, instead of continuing to uselessly follow the old file.
Captured output of command on remote host (SSH via Cron) is blank
- First, tell SSH client to not to allocate a PTY with -T option, because obviously cron doesn't have one.
- Then give it something infinite on stdin, so it will keep running until stdout
is open, we have /dev/zero exactly for this purpose.
RAW_OUTPUT=$(timeout $TIMEOUT sshpass -e ssh -T -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null $USER@$HOST "$CMD" </dev/zero 2>/dev/null)
Related Topics
Steps to Install and Run Headless Chrome Browser on Centos 6.5 Using Chrome Driver
Trying to Find All the Kernel Modules Needed for My MAChine Using Shell Script
Compile Programs on Multicore or Distributed System
How to Add JSON Object to JSON File Using Shell Script
How to Implement a Practical Fiber Scheduler
Start-Stop-Daemon Quoted Arguments Misinterpreted
Using Linux Cut, Sort and Uniq
How to "Expect" and "Send" After "Interact" Command
Linux, Print All Lines in a File, Not Starting With
What Is the Best Git Config Set Up When You Are Using Linux and Windows
200,000 Images in Single Folder in Linux, Performance Issue or Not
Bash Script to Get All Ip Addresses
How to Find Which Process Is Leaking Memory
How to Check Whether the Processor Cache Has Been Flushed Recently
Linux Terminal: How to Capture or Watch Other Terminal Session
Undefined Reference to Symbol 'Dlsym@@Glibc_2.4'
Can Malloc_Trim() Release Memory from the Middle of the Heap