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

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.

Related

Retrieving the output of SSH when launched via LSF

I'm using localhost.run to open tunnels, so I want to launch
ssh -R 80:localhost:8080 ssh.localhost.run
The only problem is that I launch it via LSF as part of a bash script.
I get the error
Pseudo-terminal will not be allocated because stdin is not a terminal.
that I solve by using the option
-T Disable pseudo-tty allocation.
My current command is
ssh -T -R 80:localhost:8080 ssh.localhost.run
and it is the last command of my bash script.
I have also tried using -tt with the same result (https://stackoverflow.com/a/7122115/5133167)
When I launch my script from my tty, I get the expected output (a message like Connect to http://user.localhost.run or https://user.localhost.run)
When I launch it through LSF (using bsub), I don't get any output from SSH (but get the output from the other commands).
I have also tried redirecting the output of ssh to a file: it works fine when launched from the command line but not when launched from LSF.

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

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.

AIX script hangs when using /dev/null > 2>&1

I am trying to run a script in AIX to execute another script on a remote server. In addition to the remote script i need to send the stdout to /dev/null. The same command works fine on another server but when I run on the current server it hangs, any advice?
su - test -c "rsh testserver /scripts/testme" 2>&1 >/dev/null1
In your comment you write that a menu is presented when the user logins.
Let's say this is done in the .profile file, using echoes and a read command.
When a menu is presented, the read command in the menu code will not be skipped by redirecting the output. The menu still waits for your input and the su command seems to hang.
Can you change your .profile or .bashrc so that it will skip presenting the menu when called using a su command? When this is called during startup, you can look at the returncode of tty. When you use the su command from the commandline, you should look for another solution.
When your root shell is ksh, you can try the following:
if [[ "$(ps -fp $$)" != *"-ksh -c "* ]]; then
echo "Now I should call the Menu"
fi

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).

How to create a screen executing given command?

i'm fairly new in *nix. Is there a way to create a screen, which will immediately execute a given command sequence (with their own arguments)? Two hours of googling yields nothing - perhaps because I can't
clearly state the question.
I hope for something like
screen -dmS new_screen exec "cd /dir && java -version"
I am using screen v4.00.03 and CentOS 5.5 (kernel ver. 2.6.18-194.26.1.el5.028stab079.2)
You create a screen with a name and in detached mode:
screen -S "mylittlescreen" -d -m
Then you send the command to be executed on your screen:
screen -r "mylittlescreen" -X stuff $'ls\n'
The stuff command is to send keystrokes inside the screen. The $ before the string command is to make the shell parse the \n inside the quotes, and the newline is required to execute the command (like when you press enter).
This is working for me on this screen version:
$ screen -v
Screen version 4.00.03jw4 (FAU) 2-May-06
Please see man screen for details about the commands.
The problem is that using the 'exec' screen command does not start a shell. 'cd' is a shell builtin, so you need a shell for it. Also, you need a shell that remains running so that screen does not terminate.
You can use the -X option to screen to send commands to a running screen session, and the 'stuff' command to send keystrokes to the current window. Try this:
screen -dmS new_screen sh
screen -S new_screen -X stuff "cd /dir
"
screen -S new_screen -X stuff "java -version
"
Yes, you need to put the quotes on the next line in order for the commands to be executed.
screen -dmS screen_name bash -c 'sleep 100'
This will create new screen named screen_name. And inside the screen it will sleep for 100 seconds.
Note that if you type some command in place of sleep 100 which terminates immediately upon execution, the screen will terminate as well. So you wont be able to see the screen you just created
I wanted to launch remote screens from within a bash script with some variables defined inside the bash script and available inside screen. So what worked for me was
#!/bin/bash
SOMEVAR1="test2"
# quit existing if there is one running already, be careful
screen -D -RR test1 -X quit || true
screen -dmS test1
screen -r test1 -p 0 -X stuff $"echo ${SOMEVAR1} ^M"
Where the return character, ^M, you need to enter using vim as
i CTRL-V ENTER ESCAPE
Another approach
First line cd to the your directory.
Second line start a new screen session named new_screen with bash.
Third line executing java -version
cd /dir
screen -dmS new_screen bash
screen -S new_screen -p 0 -X exec java -version
I think that you can use this
function exec_in_screen() {
name=$1
command=$2
screen -dmS $name sh; screen -S $name -X stuff "$command\n";
}
Then...
exec_in_screen "test" "ls"
Yes, what you want is the "stuff" command
for example
screen -dmS new_screen -X stuff "cd /dir && java -version
"
the second quote is on the next line so that it executes when sent