2
#!/bin/bash

set -o nounset
set -o errexit
trap 'echo "Aborting due to errexit on line $LINENO. Exit code: $?" >&2' ERR
set -o errtrace
set -o pipefail

SCR="bunny"
SCRIPT="/home/../run.sh" 



main() {
    if find_screen $SCR >/dev/null; then
        close_screen
        start_script
    fi
}

function start_script {
    echo "Starting script with new screen"
    screen -d -m -t $SCR sh $SCRIPT
}

function close_screen {
    if find_screen $SCR >/dev/null; then
        echo "Found! Deleting $SCR"
        screen -S -X $target_screen quit
    fi
}

function find_screen {
    if screen -ls "$1" | grep -o "^\s*[0-9]*\.$1[ "$'\t'"](" --color=NEVER -m 1 | grep -oh "[0-9]*\.$1" --color=NEVER -m 1 -q >/dev/null; then
        screen -ls "$1" | grep -o "^\s*[0-9]*\.$1[ "$'\t'"](" --color=NEVER -m 1 | grep -oh "[0-9]*\.$1" --color=NEVER -m 1 2>/dev/null
        return 0
    else
        echo "$1"
        return 1
    fi
}
target_screen=$(find_screen $SCR)
main "$@"

I am trying to create a script that restarts a specific screen. Now, the script does start the screen, but it also creates another screen with two dots 1234..randomName.

The goal of the script is to:

  • Check if screen exists
  • If exists, close screen
  • create a new screen session with SCRIPT name
  • If it doesn't exist, create screen still!

Not sure what's going or why it isn't working. What am I doing wrong?

  • Not related to the problem, but you should use standard shell function syntax instead of the function bashism. – Barmar Mar 1 '17 at 20:45
  • 1
    To see what a script is doing, put set -x at the beginning. It will then show all the commands as it executes them. This should provide some insight about where 1234..randomName is coming from. – Barmar Mar 1 '17 at 20:46
1

I got this to work with a few modifications:

#!/bin/bash

set -o nounset
# set -o errexit
# trap 'echo "Aborting due to errexit on line $LINENO. Exit code: $?" >&2' ERR
set -o errtrace
set -o pipefail

SCR="bunny"
SCRIPT="/home/../run.sh" 

function main() {
    if find_screen $SCR >/dev/null; then
        close_screen
        start_script
    fi
}

function start_script {
    echo "Starting script with new screen"
    screen -d -m -S $SCR sh $SCRIPT
}

function close_screen {
    if find_screen $SCR >/dev/null; then
        echo "Found! Deleting $SCR"
        screen -S $target_screen -X quit
    fi
}

function find_screen {

    result=$(screen -ls "$1" | grep -o "^\s*[0-9]*\.$1[ "$'\t'"](" --color=NEVER -m 1 | grep -oh "[0-9]*\.$1" --color=NEVER -m 1)

    if [ -z $result ]; then
      echo "$1"
      return 1
    else
        echo $result
        return 0
    fi
}
target_screen=$(find_screen $SCR)
main "$@"

  • I commented out the following two lines:
       set -o errexit  
       trap 'echo "Aborting due to errexit on line $LINENO. Exit code: $?" >&2' ERR  

These lines were interfering with your return 1 statement in the find_screen function

  • In the close_screen function, screen -S -X $target_screen quit needed slight modification: screen -S $target_screen -X quit to match the switches with the respective parameters.

The if statement in the find_screen function was never returning true, so I updated it slightly by adding a results variable, assigning it to your original test condition. The resulting update is as follows:

    result=$(screen -ls "$1" | grep -o "^\s*[0-9]*\.$1[ "$'\t'"](" --color=NEVER -m 1 | grep -oh "[0-9]*\.$1" --color=NEVER -m 1)

    if [ -z $result ]; then
      echo "$1"
      return 1
    else
        echo $result
        return 0
    fi

Other items

  • If you wish to name your screen based on the $SCR variable, you need to use the -S switch, as in

screen -d -m -S $SCR

... and add whatever other parameters and switches, as desired.

  • In the start_script function, looks like you're trying to use the -t switch, instead of -S, in
    screen -d -m -t $SCR sh $SCRIPT - based on your description, "create a new screen session with SCRIPT name" you would use -S to set the screen session name. You could combine this with -t to set the window name, as you may have multiple windows within a screen session: screen -d -m -S $SCR -tWindowName1
  • Hey just an update, while this works when doing ./start, when trying to use it with another script (let's say a nodejs app that runs this every minute) or a cronjob... it doesn't seem to work. The script outputs echo's from it, but that's it, no new screen is created. – kinx Mar 30 '17 at 5:07
  • Are you capturing any error messages when running the script from cronjob? – MikeD Apr 1 '17 at 14:37

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.