How to use screen to issue a command in the background over an ssh session - ssh

I am used to using linux terminals and nohup over ssh to issue commands that run in the background even when logged out of the ssh session. For some reason nohup seems to be broken in the latest MACOS. For that reason I am trying to executing this small sample script using screen command.
sleep 10
echo "this is my test file" > testfile
This file is saved as tst script. And then I issue the following command.
ssh sohaib#localhost screen -dm sh testscript
However nothing happens. screen just exits quietly without writing to the file testfile.
If I run this without ssh it works as desired. What am I doing wrong here?

The issue is that after your script exits the screen exits. The -dm is for deamons, i.e., scripts that keep running.
Showing the screen exiting after 10 seconds:
On remote host (file is executable):
ttucker#merlin:~$ cat test.sh
#!/bin/bash
echo derp > /tmp/test.txt
sleep 10
Command on local machine:
[ttucker#localhost ~]$ ssh ttucker#merlin 'screen -dmS my_screen ~/test.sh'
After run.
On remote machine, a few seconds after screen is running:
ttucker#merlin:~$ screen -ls
There is a screen on:
23141.my_screen (11/21/2016 07:05:11 PM) (Detached)
1 Socket in /var/run/screen/S-ttucker.
On remote machine, over 10 seconds later:
ttucker#merlin:~$ screen -ls
No Sockets found in /var/run/screen/S-ttucker.
Modifying the script to keep running, and so, keeping the screen up:
If you are really running a script that needs to stay up you can do the following in the script:
#!/bin/bash
while true; do
# Do something
sleep 10
done
This will do something, wait 10 seconds, then loop again.
Or, detaching the screen manually:
You can ssh to the remote machine, run screen, then press Ctrl+A,D, press Ctrl and hold, then hit A then hit D. You can now exit the SSH session and the screen will stay running.

Related

Reset status bar tmux after exiting an ssh connection started within a tmux window

I tried many things but tmux seems to be very stubborn on this one.
When I start a tmux session in bash it shows
0:bash*
in my status bar. Then when I ssh to a server it gives me
0:user#server:~*
When I then exit the ssh session, the status bar does not revert to the previous
0:bash*, it just keeps the 0:user#server:~*
which is annoying to me. I checked the man page, searched the internets, but hope the hive mind can assist me here.
This is all I have in my .tmux.conf,
set -g mouse on
set -g default-terminal "screen-256color"
tmux -V outputs tmux 2.6

Wait for a screen -X stuff "script" to finish

I have a screen instance running on remote machine. I want to execute commands on that screen like this:
ssh serverIp screen -S remote -p 0 -X stuff \"./build.sh^M\"
rsync -arvcL serverIp:/path/to/build.log build.log
The build.sh script invokes some make commands on the remote and saves it's output (using tee) to some file (let's call it build.log). Then I want to download build.log to my local machine.
How do I wait for the ./buils.sh to finish on remote, so I can download complete build.log?
You could wait for a file, created after your build script finished.
Something like
start-build.sh
#!/bin/bash
./build.sh
touch build.done
Then the command looks like:
ssh server 'rm -f build.done; screen -S remote -X stuff "./start-build^M"; while [ ! -f build.done ]; do sleep 1; done'
First it removes an old build.done file, then start the build inside the screen.
And then wait (outside of the screen) for the file build.done to exist.

bash script for screen -r

I want to make a bash script that echo's something into one of the screens that I have running (screen -r is how I get to it in SSH).
I was wondering how I would make the script execute itself in screen -r?
I basically just want the script to say something on a minecraft server through the console and would set up a cronjob to say it every x minutes.
Cheers,
You can use the -X option of screen to send commands to a running screen session.
Also the -p option is useful in this case, as you can use it to preselect a window
As an example you can run a script in a running screen session on windows 0 via:
screen -p 0 -X stuff './fancy_script.sh^M'
Note, that you have to append the return key-code to execute the script.
You can look in /dev/pts. I don't have screen here to test, but you can echo something to an opened terminal with, for example, echo "toto" > /dev/pts/0 (it will be echoed on the first opened terminal).

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.