2

I've been using screen (v4.03.01) for a while now and really like it. I've heavily customized my .screenrc, however for some odd reason the layout commands don't take on launch. If I source ~/.screenrc, they do take and my layout changes to what I want. Of note might be that I start screen with a crontab @reboot as the same user the .screenrc belongs to.

Why does this happen and how do I fix this?

Here's my .screenrc:

startup_message off
altscreen on
bell_msg "Window % wants your attention!^G"
vbell off
sorendition "= KW"
caption string "%{KW}"
defscrollback 5000
# backtick 0: get cpu usage
backtick 0 0 0 sh $HOME/.screenrc.cpu
# backtick 1: get ram usage
backtick 1 1 1 $HOME/.screenrc.ram

hardstatus alwayslastline
hardstatus string "%{= Kk}[ %{= KW}%H%{-} ] CPU: %{= KW}%0` %{-}RAM: %{= KW}%1` %{-}< %L=%-w%40L>%{= wk}%n %t%{-}%+w%-21= > [ %{= KW}%0c%{-} | %{= KW}%0d %M%{-} ]"
# %{= Kk} : set colors to black on bright black
# [       : literal
# %{= KW} : set colors to bright white on bright black
# %H      : hostname
# %{-}    : reset colors to previous (black on bright black)
# ] CPU:  : literal
# %{= KW} : set colors to bright white on bright black
# %0`     : execute backtick 0: cpu usage
# %{-}    : reset colors to previous (black on bright black)
# RAM:    : literal
# %{= KW} : set colors to bright white on bright black
# %1`     : execute backtick 1: ram usage
# %{-}    : reset colors to previous (black on bright black)
# <       : literal
# %L=     : padding anchor: prevents truncation of previous
# %-w     : previous windows
# %40L>   : padding anchor: next element is at 40% of the space between previous and next anchors
# %{= wk} : set colors to black on white
# %n      : window number
# %t      : window title
# %{-}    : reset colors to previous (black on bright black)
# %+w     : next windows
# %-21=   : padding anchor: next character is 21 characters from the right of the screen
# > [     : literal
# %{= KW} : set colors to bright white on bright black
# %c      : time (24h)
# %{-}    : reset colors to previous (black on bright black)
# |       : literal
# %{= KW} : set colors to bright white on bright black
# %d      : day of month
# %M      : three-letter month
# %{-}    : reset colors to previous (black on bright black)
# ]       : literal

# bind function keys (f1-f10) to window
bindkey "^[OP" select 0
bindkey "^[OQ" select 1
bindkey "^[OR" select 2
bindkey "^[OS" select 3
bindkey "^[[15~" select 4
bindkey "^[[17~" select 5
bindkey "^[[18~" select 6
bindkey "^[[19~" select 7
bindkey "^[[20~" select 8
bindkey "^[[21~" select 9

bindkey "^[[1;5D" prev # ctrl-left to switch to previous window
bindkey "^[[1;5C" next # ctrl-right to switch to next window
bindkey "^[[1;5B" focus # ctrl-down to switch to next region
bind = resize +1 #ctrl-= to embiggen region
bind - resize -1 #ctrl-- to shrink region

screen -t shell 0 bash
screen -t shell 1 bash
screen -t shell 2 bash
screen -t shell 3 bash
screen -t shell 4 bash
screen -t shell 5 bash
screen -t root 6 su -
screen -t something1 7 bash
screen -t something2 8 bash
screen -t something3 9 bash

#layout stuff
layout new default
layout autosave on
split -v
resize 60%
split -h
resize 15%
select 7
focus down
select 0
focus right
split -h
select 8
focus down
select 9
focus left
focus up
layout save default
layout attach default
layout select default
  • have you tried sourcing the screenrc in the bashrc? – Aaron Walerstein Feb 13 '17 at 1:11
  • I just tried this and uhh... strongly recommend against it. It'll get stuck in a loop, running it every time a bash session is started inside the screen etc. – Bab Feb 13 '17 at 1:22
  • sorry, that sounds like fun – Aaron Walerstein Feb 13 '17 at 1:24
  • I had at least 60 windows open and for some reason was completely unable to type the letter r. Saved it by scrolling up in commands until I got nano .bashrc and removed the line, then going further back up for a sudo reboot. – Bab Feb 13 '17 at 1:29
  • 1
    @AaronWalerstein One should NOT source .screenrc from bash. .screenrc is a configuration file of screen, NOT written in "bash's language" so to say. It does NOT contain bash commands, nor valid bash syntax. – egmont Feb 13 '17 at 10:23
1

You found a bug. And a nasty one at that.

The layout family of commands appear to be dependent on a controlling terminal (a TTY or PTS must be present for the command to work). I can replicate the problem without going through crontab:

I append the following to my .screenrc:

layout new lay1
split -v
layout new lay2
split -v
layout attach lay2

Running screen directly gets me the layout:

screen

But performing the following fails to find the layouts:

screen -dm && screen -r

In the last command I can still list the layouts using :layout show, but goddamn, now it is when the bug becomes nasty. If I try to change the layout (with :layout next or :layout prev), screen falls into an infinite loop.

Moreover, since the screen binary on my system is SUID root (I need multiuser support) the bug becomes worse. Once the user process has been killed the root process starts an infinite loop and eventually crashes. A possibility of crashing an SUID process, or even just capability of creating several root processes sucking CPU resources in infinite loops, is very dangerous.

I have tested it on your version of screen (4.3.0) and also on 4.5.0 (the latest version) where the bug still exists. I'm in the process of compiling the source with -DDEBUG and reporting the bug to the development team of screen. The -DDEBUG screen fails with:

ASSERT(l->l_cvlist != cv) failed file canvas.c line 294

Therefore it is likely that the infinite loop tries to find something in that linked list and fails over and over.

Hacky workaround

screen allows you to bind the eval method. Therefore you can add to your .screenrc something like:

bind g eval 'layout new default' 'split -v' 'resize 60%' 'split -h' 'layout select default'

The hacky part is that it must be on a single line, screen does not have any way of escaping long lines in .screenrc. Then you can get your layout with a single (well double) keystroke after you get into the screen (Ctrl+ag).

g is normally bound to the system bell, so you should not miss it. But you can bind any key you like.

  • Oh dear, that's quite something. I can't believe no one has run into this before (and reported it), especially with the whole looping part. I guess I'm lucky I just never tried switching layouts ;) Since it's probably gonna take a while to get this fixed, what alternatives do you recommend? – Bab Feb 14 '17 at 15:46
  • 1
    @MarcBabtist - added a hacky workaround. Since you have the commands bound, you will execute them once you are attached to screen. And when the screen is attached a TTY is present for the layour to work. – grochmal Feb 14 '17 at 16:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.