How to make GNU screen auto start when login? - linux

I have several linux servers to work on every day, and I have a GNU screen session on each of them to preserve work progress.
The question is I am so tired of issue screen -Rd work every time I login, is there anyways to get rid of that? Or any workarounds?
Reading #Sami's answer, I did some search on the $STY shell variable and found this:
STY: Alternate socket name. If screen is invoked, and the environment variable STY is set, then it creates only a window in the running screen session rather than starting a new session.
So I think the key is the $STY variable, we may append it to either .bashrc or .profile, as long as it gets executed upon login. Thanks #Sami

This depends on your shell. In case you use any of Bourne Shell derivatives (namely Bash) or Bourne Shell itself, put appropriate commands in ~/.profile:
[ -z "$STY" ] && screen -Rd "work"
This will only start a screen session in case you're not already running inside a screen session (screen sets environment variable STY).
In case you're not using Bash or compatible, use the proper shell initialization file with a similar test.

You could put an alias in your login script:
alias s="screen -Rd work"
then you'd only have to type
s

Related

How to track file creation and modification

We have put together a perl script that essentially looks at the argument that is being passed to it checks if is creating or modifying a file then it saves that in a mysql database so that it is easily accessible later. Here is the interesting part, how do I make this perl script run before all of the commands typed in the terminal. I need to make this dummy proof so people don't forget to run it.
Sorry I didn't formulate this question properly. What I want to do is prepend to each command such that each command will run like so "./run.pl ls" for example. That way I can track file changes if the command is mv or it creates an out file for example. The script pretty much takes care of that but I just don't know how to run it seamlessly to the user.
I am running ubuntu server with the bash terminal.
Thanks
If I understood correctly you need to execute a function before running every command, something similar to preexec and precmd in zsh.
Unfortunately bash doesn't have a native support for this but you can do it using DEBUG trap.
Here is a sample code applying this method.
This page also provide some useful information.
You can modify the ~/.bashrc file and launch your script there. Do note that each user would (and should) still have the privelege to modify this file, potentially removing the script invocation.
The /etc/bash.bashrc file is system-wide and only changeable by root.
These .bashrcs are executed when a new instance of bash is created (e.g. new terminal).
It is not the same as sh, the system shell, that is dash on Ubuntu systems.

How do I get GNU screen to read .bash_profile/.bash_rc changes?

After I make changes in .bash_rc or .bash_profile, when I start GNU screen, it doesn't recognize those changes.
I can
source ~/.bash_profile
and it works for the current screen window I have open, but I have to do that for every screen window I have open.
How do I get screen to read my latest changes in my bash configuration?
If you want screen to always treat your shell as a login shell, and source the same files that would be read if just started a new shell normally, add the following to ~/.screenrc (or maybe ~/.byobu/.screenrc, as pointed out in the comment):
shell -$SHELL
This way, you don't need to manually tell it to source your files each time you start a new screen. Though you would have to if you just made changes and wanted those changes to be reflected in your current screen.
The documentation for this (and lots of other screen details) can be found here. Basically, shell is a command to screen telling it to run the following when it needs to create a new shell. $SHELL is the usual variable holding the path to your preferred shell. And the dash - in front of $SHELL indicates that it should be run as a login shell (which will typically mean it sources your ~/.bash_profile, etc.).
It's worth pointing out, however, that screen defaults to just inheriting most environment variables from the shell where you start screen; and a login sub-shell may alter some environment variables in unexpected ways. I ran into a situation where elements of my $PATH were basically permuted. I solved the problem thanks to this particularly excellent answer on superuser.
You may notice the source command available. It's important to note that this sources a file of screen commands, rather than shell commands. Other relevant (screen) commands include eval and exec.
You have to do it in each screen that you have open since they are all different shells. If you need the change every time a new shell is opened, I suggest you put the changes in ~/.bashrc instead.
Apparently, you can send a command to all windows at once using this syntax:
C-a :
at "#" stuff "source ~/.bash_profile^M"

Launch multiple scripted screen sessions from another script

I've written a script (that doesn't work) that looks something like this:
#!/bin/sh
screen -dmS "somename" $HOME/somescript.sh
j=13
for i in {0..5}; do
screen -dmS "name$i" $HOME/anotherscript.sh $i $j
j=10
done
If I copy and paste this into a terminal, it creates 7 detached screen sessions, as I expect. If I run it from within a script, however, I get only the first session, "somename," when I run screen -ls.
I realize screen can be used to create multiple windows within one session. It doesn't really matter to me how these scripts get run. I just want to get to the bottom of why this doesn't work as a script.
Note: I've asked this question on SuperUser without any suitable responses. I figured maybe that's the wrong place to ask what could be considered a programming question.
One thing you might be getting bitten on is which specific version of which specific shell you're running. /bin/sh could actually be bash, or it could be bourne, and that can make a difference on how your loop syntax is interpreted. The {0..5} construct isn't understood in older versions of bash (v2.x), for instance, nor in bourne (at least it wasn't when I finally managed to track down a /bin/sh that was a real, live bourne shell :-).
My suggestion is to change your shebang line to /bin/bash if you need its syntax, and check that your bash is version 3.x or later. Since you say it works from the commandline, my bet is on the shebang line, though.

Why is exported variable blank after script is over?

I have a simple command in a Linux shell script (say foo.sh). In it I do this:
export INSTALL_DIR=/mnt/share/TEST_Linux
I run the script with:
> sh foo.sh
When it finishes I try to get the variable but the value is blank.
> echo $INSTALL_DIR
If I type the command directly the exported var becomes global to the opened terminal window. I'm using Ubuntu.
Setting environment variables is local to the child bash process running your script. To achieve what you want, you need to source it like this: source foo.sh. It means that it's run by your main bash process. Then, the setting of a variable will remain after the script is finished.
The variable is exported only in the new shell you are starting. You probably want to execute your script with source.
source foo.sh
I don't know the answer but i know how to overcome it.
# source ./foo.sh
# echo $INSTALL_DIR
And it's like magic.
I think it's because that script gets executed in it's own "shell". Not sure.
Because the process you are running (the shell running your script) can do whatever it wants, but its actions won't affect the parent process (your current shell).
A somewhat weird analogy would be: I can take 5 tequila shots and my environment will become blurry and gravity laws would be affected according to my perception. But to my father, his environment is the same, he doesn't get drunk because of my actions.
If you want that variables created/altered in your script affect your current shell, you should source the script as other answers pointed out. Please do note that doing this also may change the resulting working dir in your shell if the script does cd /whatever/path, that any other functions setted, but also altered or removed, would get affected in the same way in your shell.
A really weird and not very good analogy would be if I take 5 tekila shots and then my father kills me and drinks my blood.
Am I disturbed or what? ;-)

SSH, screen and XDISPLAY

I use screen to persist my work session and connect to the same session from multiple machines. How can I setup SSH and screen such that the XDISPLAY variable inside my persistent screen session is always set to the machine I am currently connecting from?
ie. I start the screen session at work and use gvim, which uses the X server running on my work machine. Later, I connect to the same session from home and also want to use gvim. But this time, I want gvim to use the X server on my home machine. I realize I could manually update XDISPLAY every time I connect from a different machine but I'd rather have an automated system.
Bonus points if I can actually move gvim from my work machine to my home machine while it is running. I tried xmove but could never get it to play nice.
The following is a manual solution, but there's no reason you couldn't
use an alias or a script to have it done automagically when you remotely log in.
Assuming that your local shell sets the DISPLAY variable appropriately,
you could use screen -X to send the following commads to your remote screen before
connecting.
# set future remote shells started by screen to have the correct XDISPLAY
% screen -X "setenv XDISPLAY $DISPLAY" #...
# set up the keystroke F1 to update the XDISPLAY in current shells
% screen -X "bindkey -k k1 stuff export XDISPLAY=$DISPLAY\015" #...
If you know that all your windows were left in a shell (not a running editor or some such), you could use :at to change the XDISPLAY rather than a key binding:
# update the XDISPLAY in all current windows
% screen -X "at % stuff export XDISPLAY=$DISPLAY\015" #...
Alternately, if you know some way of grabbing a parent process's environment variable value, then you could use that together with your shell's prompt hook to grab SCREEN's value of XDISPLAY (as set by setenv) and update it for the shell.
There is no "trivial" way to change environment variables in foreign processes.
A straightforward solution might be to persist your XDISPLAY into a file on login and use a PROMPT_COMMAND to read this file before printing the next prompt.
For moving X applications around look at something like X11vnc or Xvnc.

Resources