How to attach to existing screen session or create a new one and run a command? - gnu-screen

I'm using
screen -RdS SessionName
To attach to existing session if exist or create a new session and attach to it. I also have
screen -RdS SessionName -X stuff 'ls -l'`echo -ne '\015'`
To run a command in a screen session. However, I expect to be inside the screen session after this command. What is the command which does what the first does but also runs some command inside screen?

For now the following solution completely satisfies me
screen -S SessionName -X stuff 'ls -l'`echo -ne '\015'`; screen -RdS SessionName

Related

how to create a GNU screen session with multi windows in it?

I alway work in a screen session with some windows, one for shell, one for mysql, one for music player, one for irc, and so on...
The problem is, when you create a screen session, it only creates one window by default. So I have to do Ctrl-a c then issue commands, again and again.
So I wrote a bash function to do this.
d(){
local i=workspace
screen -qls $i
if [ "$?" -ne 11 ];then
screen -dmS $i
screen -S $i -X screen mysql -uroot -p
screen -S $i -X screen irssi
screen -S $i -X screen nvlc $music -Z
screen -r $i -p0
else
screen -r $i
fi
}
My question is, is there a way to start a new screen session with some windows? By this question, I mean new session, NOT for existing sessions using '-X'. And, screen built-in feature, I mean, no shell scripting involved.
I didn't consider .screenrc file at first, because commands in it will be invoked every time you call screen, but sometimes I need to create a new screen session with different things.
One thing I forgot is that, I can choose configuration file.
So I think answer is:
d(){
screen -d -R -S workspace -c ~/.workspace
}
and content of ~/.workspace should be:
screen
screen mysql -uroot -p
screen irssi
screen nvlc
select 0

How to list tabs within a screen session from command line while detatched

I am trying to figure out a way to list all of the tabs in a specific screen session from command line. Specifically, I just want to figure out if a tab exists of some particular name.
I have a script which creates a new tab in a session and runs a script there for a list of tab names. For some reason, there are occasionally one or two tabs that don't get created and this throws off the top level script. I want to add an acknowledgement in my top level script that checks if the particular tab was created and, if not, have a log that tells me this when I go back and look at the data.
Here is my top level code snippet, in case you may have any pointers on why a particular tab would not get created. My guess is that the tabs get created too quickly and this potentially causes an error. There are definitely no name conflicts
for f in $PWD/*; do
if [ -d $f ]; then
CMD="cd $f; bash cmd"
# Creates a new screen window with title '$f' in existing screen session
screen -S $SESSION_NAME -X screen -t $f
# Switch terminal to bash
screen -S $SESSION_NAME -p $f -X stuff "bash$(printf \\r)"
# Launch $CMD in newly created screen window
screen -S $SESSION_NAME -p $f -X stuff "$CMD$(printf \\r)"
fi
done
Thanks for the help!
You can use the -Q parameter with the command windows
-Q Some commands now can be queried from a remote session using this flag, e.g. "screen -Q windows". The commands will send the response to the
stdout of the querying process. If there was an error in the command, then the querying process will exit with a non-zero status.

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

how do you script gnu screen from within a screen session to open new windows and run commands in them?

From within a screen session, I'd like to run a shell script that opens
a few new screen windows in the same session and start running some
programs in them.
I need a script like this:
screen -t newWindow
[switch to newWindow and execute a command]
screen -t newWindow2
[switch to newWindow2 and execute a command]
I don't know how to accomplish the effect I describe in the brackets.
Any clues? Please note that this is not a script I'll be running to start a screen session. I need this script to be runnable within an existing screen session, in order to add new windows to the session.
Note: you can't launch script working following way from a screen session. And it will open in session no tabs... Its more a related tip than a real answer to the question.
There is an other solution, if you accept to have a screen session by running process...
new session script
#!/bin/sh
echo "nouvelle session screen ${sessionName}"
screen -S ${sessionName} init.sh
echo "screen session: done"
echo "go to ${AnyWhere}"
sleep 1
screenexec ${sessionName} "cd ${AnyWhere}"
init script (here "init.sh")
#!/bin/zsh
zsh -c "sleep 0.2"
screen -d #detach the initialised screen
zsh #let a prompt running
injection script (here screenexec)
#!/bin/sh
# $1 -> nom de screen cible $2 -> commande
echo "injection de «${2}» dans la session «${1}» ..."
screen -x "$1" -X stuff "$2" #inject the command
screen -x "$1" -X eval "stuff \015" #inject \n
echo "Done"
By using this way, you should inject code easily in your screens, interesting if your script act like a deamon...
For those who prefer script in python, I've made a small lib to create sessions, close sessions, inject commands: ScreenUtils.py
It's a small project, which don't handle multiwindows screen sessions.
Forgot to mention I made a real python library out of it long ago: https://github.com/Christophe31/screenutils
Running this script inside screen does what I think you want:
#!/bin/bash
screen vi
screen top