Is there a way to automate split-screens in GNU Screen? - gnu-screen

I know this is possible manually via ctrl commands using gnu screen for linux but I cannot seem to find a way to do this using only a script.
What I am trying to accomplish is via script having gnu screen split my terminal screen horizontally and run two separate commands on each screen at the same time.
For instance using two separate watch ls folder commands
[screen 1] watch ls folder1
[screen 2] watch ls folder2

Your .screenrc file gets interpreted in order, sort of like running the Ctrl-A commands yourself.
$ cat .screenrc
screen -t folder1 1 watch ls /path/to/folder1
screen -t folder2 2 watch ls /path/to/folder2
sessionname Hello
split
select 1
focus
select 2
startup_message off

Related

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.

Command works in shell but not Objective-C or C

I want to run the following shell command in Objective-C
sshfs -C -p 22 user#remote.computer.com ~/local/directory/path
using the command system("sshfs -C -p 22 user#remote.computer.com ~/local/directory/path");
but I get sh: sshfs: command not found in NSLog.
If I copy and paste it into terminal however, it works.
The path used by an GUI application does not include any changes you have made in your shell files in your home directory (e.g. ~/.bashrc)
One way is to use the full path in the system call. (i.e. /Users/username/Projects - ~ are not automatically expanded) In a Cocoa app I would use NSTask to give more control

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 get a custom Gnu screen config to load .bash_profile and .bash_aliases?

I have a custom screen configuration myscreenconfig and a .screenrc. myscreenconfig looks like this:
source .screenrc
screen 0 bash
title 'notes'
screen 1 bash
title 'bash'
[etc.]
.screenrc has these lines at the top:
altscreen on
shell -${SHELL}
My .bash_profile file sets a lot of things and then calls source $HOME/.bash_aliases.
If I start screen without any arguments, my .bash_profile gets loaded and .bash_aliases gets loaded. But if I start screen via screen -c myscreenconfig, only .bash_profile gets loaded, and not .bash_aliases. Why? How can I fix this?
What worked for me was making a symbolic link between wherever I had my bash settings and .bashrc (which I did not have):
ln -s ~/.bash_profile ~/.bashrc
I had the same problem on one of the machines I use. After reading the suggestion above about linking the two bash resource files, I realized that the following section had been put in comment in the .bash_profile file on this particular machine:
# Get the aliases and functions
# if [ -f ~/.bashrc ]; then
# . ~/.bashrc
# fi
After removing the comment signs (#) from before the if block lines, settings in .bashrc became available in screen sessions as well.
Because you are not using login shells in myscreenconfig. Use (IIRC) screen 0 -bash, or try combinations with deflogin on.
I'm use this in my .bashrc
if [ "$TERM" = "screen" ]; then
if [ -f ~/.bash_profile ]; then
. ~/.bash_profile
fi
fi