-   Linux - General (
-   -   how to run the screen program WITHOUT clearing the display (

Skaperen 07-21-2013 06:12 PM

how to run the screen program WITHOUT clearing the display
I have a script which runs a few programs where the output scrolls up in the normal text way. There is one program the script runs I have a reason to run it inside screen. But I would like this program's output to just work like the others, and be output at the bottom of the display and scroll up like everything else. It will eventually finish in a few seconds, in which case it will exit, and screen should exit, and the script will go on to the next program as usual.

But screen clears the display because screen wants to manage it all. Any idea how to disable this?

Firerat 07-21-2013 06:21 PM

start detached?

from man screen ( Screen version 4.01.00devel (GNU) 2-May-06 )


      -d -m  Start screen in "detached" mode. This creates a new session but doesn't attach to it. This is useful for system startup scripts.

      -D -m  This also starts screen in "detached" mode, but doesn't fork a new process. The command exits if the session terminates.

No idea if that fits your context, no real context to fit.

Skaperen 07-21-2013 06:34 PM

It needs to stay attached so it's output is shown and scrolls up like other output in the script, from the other programs it runs. I just don't want it blanking out the previous output. Someone watching the display should not really seen that screen was even run, although a few lines of output at the start and end could be tolerable. The program that will be run in screen will output about 3 to 6 lines. Those lines need to be seen below the output from previous programs, and above the output of programs that are run afterwards.

I'm using the detached method now, and I cannot see the output of the program being run.

Firerat 07-22-2013 06:34 AM

OK, I think I better understand now..

I don't know if this will be suitable, but -L will produce an output log, which you could then view with cat screenlog.0

I was going to say use tail -f, but that tail will never exit.

Dumb example


for i in {1..9};do
    echo "line $i"
rm screenlog.0
coproc screen -DmL df -h
sleep 1
cat screenlog.0
for i in {9..18};do
    echo "line $i"

Probably Doesn’t fit..
I don't know what you are running in your screen session or where that screen is ( local/remote or if brand new )

Skaperen 07-22-2013 09:38 AM

The task being run in screen is an rsync command to transfer /root/.ssh files over to the target host. It uses ssh. The very first time there will be an ssh password prompt. Screen is being used to stuff in the password to ssh which reads it from /dev/tty instead of stdin. Thereafter I can use ssh keys, so this is just a one-time thing per host. I start the background thing like this:

screen -S "${SESSION}" -p 0 -dm rsync -avWz {${overlaytree},root@${TARGETHOST}:}/root/.ssh/.
Then I run these commands to stuff in the password:

sleep 5
x=$(printf '%s\r' "${PASSWORD}")
screen -S "${SESSION}" -p 0 -X stuff "${x}"

This works, but I want to see the rsync command output in the scrolled output. If I take out the "-d" then I do see the output, but with the display blanking happening.

Firerat 07-22-2013 11:36 AM

Ok, in that case I think you can use -L, and follow screenlog.0 with tail -f in background, terminating it when screen exits ( by monitoring PID )


screen -S "${SESSION}" -p 0 -DmL rsync -avWz {${overlaytree},root@${TARGETHOST}:}/root/.ssh/. &
sleep 5
x=$(printf '%s\r' "${PASSWORD}")
screen -S "${SESSION}" -p 0 -X stuff "${x}"

tail -f screenlog.0 &

while $( pgrep screen | grep -q $PID_SCREEN );do
    sleep 1

kill -15 $PID_TAIL
wait $! 2>/dev/null # avoids "Terminated tail -f screenlog.0" 'pollution'

Couple of things to note:

here I have used -Dm instead of -dm, this is so I can get pid of last bg job ( with $! )

by default screenlog.n ( where n is screen number ) is in current working dir, to change this you have to customise the .screenrc file ( unless things have changed and you can specify on command line, which would be much nicer )

Skaperen 07-22-2013 11:24 PM

It is possible to see when a file has another process open to it. The "tail" command should add an option to have it exit when the writer closes.

I could loop around testing the file with "fuser" to see when it is no longer open to another process, and avoid the mess with PIDs.

Firerat 07-22-2013 11:42 PM

actually, yeah

man tail ( tail (GNU coreutils) 8.13 )


              with -f, terminate after process ID, PID dies

so much cleaner

screen -S "${SESSION}" -p 0 -DmL rsync -avWz {${overlaytree},root@${TARGETHOST}:}/root/.ssh/. &

sleep 5
x=$(printf '%s\r' "${PASSWORD}")
screen -S "${SESSION}" -p 0 -X stuff "${x}"

tail --pid=$PID_SCREEN -f screenlog.0

Skaperen 07-23-2013 12:39 AM

I want to avoid doing it by PID because -Dm is still blanking the display. Using -dm drops it in the background so I cannot reliably get the PID. But I don't need the PID since fuser can tell me when the file is no longer open.

Here's what I have lately tried:

echo "Testing if ssh can login using a key pair"
ssh=( ssh -o 'batchmode yes' "root@${dsthost}" )
rsync=( rsync -e 'ssh -o "batchmode no"' -avWz ${cwd}/noarch/root/.ssh/. ${dsthost}:/root/.ssh )
if ! "${ssh[@]}" 'echo YES' ; then
    if [[ -n "${PW}" ]] ; then
        echo "Transferring authorized_keys file to avoid future password prompts"
        unique=$( exec date "+%Y%m%d%H%M%S%N${pid}" )
        echo "logfile ${logfile}" > "${cfgfile}"
        ls -dl "${cfgfile}"
        screen -c "${cfgfile}" -S mods-rsync -p 0 -dm "${rsync[@]}"
        sleep 5
        screen -S mods-rsync -p 0 -X stuff $( printf '%s\r' "${PW}" )
        while fuser "${logfile}" 2>/dev/null ; do sleep 1 ; done
        cat "${logfile}"
#      rm -fv "${cfgfile}" "${logfile}"
        "${ssh[@]}" 'ls -dl /root/.ssh/authorized_keys' || fail "Transfer of authorized_key file to ${dsthost} failed"
        echo 'Enter the root password for ${dsthost} to transfer the .ssh/authorized_keys file:'
        "${rsync[@]}" || exit 1

But this still fails because the log file is not being written. I think I have it set up correctly in the config file, and -c is used to refer to the config file. And at least 5 should be enough time for the log file to be opened. Yet it doesn't write the log file. The rsync does run, does get the password being stuffed in, and does transfer the ssh files. Screen is just not logging it. Does screen need to stay in the foreground to log it (e.g. the client side does the logging instead of the server side)? If so, I'll try some other way to get log output. The output looks like this:

Testing if ssh can login using a key pair
Warning: Permanently added 'planck,' (RSA) to the list of known hosts.
Permission denied (publickey,password,keyboard-interactive). this is the test on the if command
Transferring authorized_keys file to avoid future password prompts
-rw-r--r-- 1 root root 57 Jul 23 01:34 /tmp/mods-rsync-2013072301341102456990623720.cfg
cat: /tmp/mods-rsync-2013072301341102456990623720.log: No such file or directory the file is not there
Warning: Permanently added 'planck,' (RSA) to the list of known hosts.
-rw------- 1 root root 71808 Oct  2  2012 /root/.ssh/authorized_keys it got this file anyway

Firerat 07-23-2013 01:31 AM

You need to turn logging on with -L
( the logfile in the config just overrides the default /location/name )


screen -c "${cfgfile}" -S mods-rsync -p 0 -dmL "${rsync[@]}"
Not sure why you are seeing blanking with -Dm

here is my test script

for i in {1..10};do
  echo $i
screen -p 0 -DmL find ~/Downloads  &
tail --pid=$! -f screenlog.0
echo Done

Simple, but enough for me to see no blanking

Skaperen 07-23-2013 12:48 PM

It is working now. I guess telling it what logfile to use is not sufficient for it to know to actually do it.

All times are GMT -5. The time now is 07:30 AM.