Screen GNU Script Bash - linux

I want to do a script, to automatize my tasks while I start my PC.
The main idea is to use screen to do it.
I wrote this, but It doesn't work. Only it builded the first session and then nothing more.
This is the code
#!/bin/bash
screen -dmS angular sh -c 'cd Documents/segdet; ng serve --env=local'
screen -dmS jboss1 sh -x -c 'cd Documents/keycloak-2.3.0.Final/bin; ./standalone.sh -Djboss.socket.binding.port-offset=100 -b 0.0.0.0 &'
screen -dmS jboss2 sh -x -c 'cd Documents/wildfly-10.1.0.Final/bin; ./standalone.sh -b 0.0.0.0 &'

You need to use screen's -d option to get the screen session to disconnect after starting so it will move to the next one in the script.
Also using -S is useful to name the session so you can connect to the correct one later.
Something like this:
#!/bin/bash
screen -dmS angular sh -c 'cd Documents/file1; ng serve --env=local'
screen -dmS jboss1 sh -x -c 'cd Documents/file2/bin; ./standalone.sh -Djboss.socket.binding.port-offset=100 -b 0.0.0.0 &'
screen -dmS jboss2 sh -x -c 'wil' 'cd Documents/file3/bin; ./standalone.sh -b 0.0.0.0 &'
This will start 3 screen sessions named angular, jboss1 and jboss2

Related

Pass environment variables to nested children

I have some environment variables that are being set, and am trying to access them via a child process of a child process. I am trying to use shell to start another process. In my example it is just another shell script to keep things simple.
I went through the shell documentation, and tried using the -a flag and that did not work. It will work if i explicitly copy over the env variables from the parent to the child.
a.sh
#!/bin/sh
# does not work here
echo $FOO
parent.sh
#!/bin/sh
export FOO=bar
sudo -H -u username nohup sh -c "echo $FOO #works here; sh ./a.sh"
It will however work if i explicitly pass in FOO to the inline shell script
#!/bin/sh
export FOO=bar
sudo -H -u username nohup sh -c "echo $FOO;export FOO=$FOO; sh ./a.sh"
Is there a more elegant solution to passing env variables to nested children?
In my actual implementation code, it is not a shell script I am trying to use, but starting another process that depends on the env variables, so sourcing a script would not be viable.
Because sudo does not preserve environment by default when starting new process, you should instruct it to keep a certain var explicitly:
sudo FOO=100 -H -u username nohup sh -c "sh ./a.sh"
nohup: ignoring input and appending output to ‘nohup.out’
cat nohup.out
100
sudo does not preserve the caller's environment unless you use the -E option, and even then sudo must be configured to allow the environment to be preserved for a given user or command.
Your first example, sudo -H -u username nohup sh -c "echo $FOO #works here; sh ./a.sh", is equivalent (after shell processing) to
sudo -H -u username nohup sh -c "echo bar; sh ./a.sh"
but the sh process started by sudo won't have FOO in its environment.
(sudo -H -u username -E nohup sh -c "sh ./a.sh" might work, though, depending on the local security policy. -E is a request, not a command.)
Your second example, after shell processing, is
sudo -H -u username nohup sh -c "echo bar;export FOO=bar; sh ./a.sh"
Here, sh isn't inheriting FOO from the shell that calls sudo; instead, you are running a shell process that itself defines a new variable FOO in its environment, which a.sh then inherits.

Send command inside screen from an other user via bash

Lets say:
I have 2 users: root and mc.
I want to run a command inside a screen which is located on mc, but i need to run the script as root.
This is what I came up with:
sudo -u mc -H sh -c "screen -r lobby -p 0 -X stuff "restart $(printf '\r')""
I guess, using 2 ' " ' wont work, so how do I manage this problem?
If you use double quote inside a double quoted string, just add \ in front of it to skip it.
sudo -u mc -H sh -c "screen -r lobby -p 0 -X stuff \"restart $(printf '\r')\""

How to "setup" screen using a bash script

I'm trying to write a bash script to create a screen (software) session with a specific set of windows, and cd to specific directories on each one.
Here is the script I have so far:
#!/bin/bash
killall screen;
screen -AmdS work;
screen -S work bash -c "cd myDir";
The problem is that I can't seem to change directories on that session. After running this script, I run $ screen -r and the current directory is still my default directory (~/).
(I've tried changing the cd command to touch myFile and the file is there after I run the script)
Try the following, it will open a new screen session with a bash which will change the directory and open a new bash with this directory as current:
screen -S work bash -c 'cd myDir && exec bash'
Adding -d -m to run it in detached mode. And after reattaching you will be in myDir:
screen -S work -d -m bash -c 'cd myDir && exec bash'
Better solution
The following code will create a detached screen with 3 screens each running myCommand1/2/3 in directory myDir1/2/3.
cd myDir1
screen -S work -d -m
screen -S work -X exec myCommand1
screen -S work -X chdir myDir2
screen -S work -X screen
screen -S work -X exec myCommand2
screen -S work -X chdir myDir3
screen -S work -X screen
screen -S work -X exec myCommand3
cd -
Note the last cd - that will return you back to your original working directory.
Finally just use screen -r work to attach your running screen session.
You can save the command line you want to run (including the final newline) into a register and paste it into the screen input:
screen -S work -X register c $'cd myDir\n'
screen -S work -X paste c

Execute command on specific screen on CentOS

I use screen on CentOS to run my script. Example:
Output command screen -ls:
There is a screen on:
session-1 (Detached)
1 Socket in /var/run/screen/S-root
And I Run:
screen -r -S "session-1" -d -m -p 0 /tmp/script1.sh
screen -r -S "session-1" -d -m -p 1 /tmp/script2.sh
screen -r -S "session-1" -d -m -p 2 /tmp/script3.sh
but it's not work. I want script1.sh run on screen:0, script1.sh run on screen:1, script1.sh run on screen:2,... with option -p <screen number>. But it's not work. Please help me.
Thanks!
i have 10 window in session-1 and i want to run 10 script.
Since session-1 and its windows have already been created, we don't need options -d -m. Also, of options -r -S we need only one. To execute a program in an already existing session we need option -X exec …. So, the resulting commands would be like:
screen -r session-1 -p 0 -X exec /tmp/script1.sh
But when I tried this with screen versions 4.0, the program was executed in the current (last used) window, not in the window specified by -p. Apparently -p doesn't work with -X. What did work was:
screen -r session-1 -p 0 -X stuff /tmp/script1.sh$'\n'
screen -r session-1 -p 1 -X stuff /tmp/script2.sh$'\n'
screen -r session-1 -p 2 -X stuff /tmp/script3.sh$'\n'

How do I start multiple screens with custom commands for each one?

I want to start multiple screens using the mac/linux command screen and have each screen execute my .bashrc and then run a series of aliases/functions from that .bashrc. I have tried adding various commands in my .screenrc as shown below:
screen -t first bash
screen -t SE bash
screen -t myserver bash -i --rcfile <(echo "export PS1='> ' && ls") -i
screen -t myserver bash -i
screen -t myserver /Users/user/bin/mybash
screen -t myserver mybash
screen -t myserver ~/bin/mybash
screen -t myserver bash --init-file <(echo "source .bashrc; runapp")
screen -t myserver2 bash --init-file <(echo ". .bashrc; runapp")
but the aliases don't get executed. What am I doing wrong?
Ok, here is how you can use aliases with screen.
~$ cat .profile
shopt -s expand_aliases
alias ping1="ping 8.8.8.8"
alias ping2="ping 8.8.4.4"
~$ cat .screenrc
screen -t app1 bash -lc ping1
screen -t app2 bash -lc ping2
~$ screen
Even though, it's possible to achieve it doesn't feel like a great idea. People are avoiding "expand_aliases" for reason.

Resources