将命令发送到GNU屏幕

| 我有一个名为demo的GNU屏幕,我想向它发送命令。我该怎么做呢?
screen -S demo -X /home/aa/scripts/outputs.sh
No screen session found.
并执行
screen -ls
表示它没有运行。     
已邀请:
如果“屏幕”会话未运行,则无法向其发送消息。首先启动。 进行会话后,您需要区分屏幕命令和键盘输入。
screen -X
需要屏幕命令。
stuff
命令发送输入,并且如果您想从shell提示符下运行该程序,则还必须传递换行符。
screen -S demo -X stuff \'/home/aa/scripts/outputs.sh
\'
请注意,这可能是错误的方法。您确定要键入该会话中处于活动状态的内容吗?要将输入定向到特定窗口,请使用
screen -S demo -p 1 -X stuff \'/home/aa/scripts/outputs.sh
\'
其中1是窗口号(您可以改用其标题)。 要在该会话中启动新窗口,请改用
screen
命令。 (这是
screen
Screen命令,而不是
screen
shell命令。)
screen -S demo -p 1 -X screen \'/home/aa/scripts/outputs.sh\'
    
我将它们放在一起以捕获命令的输出。如果您希望通过管道输入某些内容,它也会处理stdin。
function xscreen {
    # Usage: xscreen <screen-name> command...
    local SCREEN_NAME=$1
    shift

    # Create screen if it doesn\'t exist
    if ! screen -list | grep $SCREEN_NAME >/dev/null ; then
        screen -dmS $SCREEN_NAME
    fi

    # Create I/O pipes
    local DIR=$( mktemp -d )
    local STDIN=$DIR/stdin
    local STDOUT=$DIR/stdout
    local STDERR=$DIR/stderr
    mkfifo $STDIN $STDOUT $STDERR
    trap \'rm -f $STDIN $STDOUT $STDERR; rmdir $DIR\' RETURN

    # Print output and kill stdin when both pipes are closed
    { cat $STDERR >&2 & cat $STDOUT & wait ; fuser -s -PIPE -k -w $STDIN ; } &

    # Start the command (Clear line ^A^K, enter command with redirects, run with ^O)
    screen -S $SCREEN_NAME -p0 -X stuff \"$(echo -ne \'\\001\\013\') { $* ; } <$STDIN 1> >(tee $STDOUT) 2> >(tee $STDERR >&2)$(echo -ne \'\\015\')\"

    # Forward stdin
    cat > $STDIN

    # Just in case stdin is closed
    wait
}
更进一步,通过ssh调用此函数可能很有用:
ssh user@host -n xscreen somename \'echo hello world\'
也许将其与诸如ѭ13之类的东西结合使用,因此您不必具有已在远程主机上定义的功能。 bash脚本中用于处理返回状态和语法错误的较长版本:
#!/bin/bash

function usage {
    echo \"$(basename $0) [[user@]server:[port]] <screen-name> command...\" >&2
    exit 1
}

[[ $# -ge 2 ]] || usage

SERVER=
SERVERPORT=\"-p 22\"
SERVERPAT=\'^(([a-z]+@)?([A-Za-z0-9.]+)):([0-9]+)?$\'
if [[ \"$1\" =~ $SERVERPAT ]]; then
    SERVER=\"${BASH_REMATCH[1]}\"
    [[ -n \"${BASH_REMATCH[4]}\" ]] && SERVERPORT=\"-p ${BASH_REMATCH[4]}\"
    shift
fi

function xscreen {
    # Usage: xscreen <screen-name> command...
    local SCREEN_NAME=$1
    shift

    if ! screen -list | grep $SCREEN_NAME >/dev/null ; then
        echo \"Screen $SCREEN_NAME not found.\" >&2
        return 124
        # Create screen if it doesn\'t exist
        #screen -dmS $SCREEN_NAME
    fi

    # Create I/O pipes
    local DIR=$( mktemp -d )
    mkfifo $DIR/stdin $DIR/stdout $DIR/stderr
    echo 123 > $DIR/status
    trap \'rm -f $DIR/{stdin,stdout,stderr,status}; rmdir $DIR\' RETURN

    # Forward ^C to screen
    trap \"screen -S $SCREEN_NAME -p0 -X stuff $\'\\003\'\" INT

    # Print output and kill stdin when both pipes are closed
    {
        cat $DIR/stderr >&2 &
        cat $DIR/stdout &
        wait
        [[ -e $DIR/stdin ]] && fuser -s -PIPE -k -w $DIR/stdin
    } &
    READER_PID=$!

    # Close all the pipes if the command fails to start (e.g. syntax error)
    {
        # Kill the sleep when this subshell is killed. Ugh.. bash.
        trap \'kill $(jobs -p)\' EXIT

        # Try to write nothing to stdin. This will block until something reads.
        echo -n > $DIR/stdin &
        TEST_PID=$!
        sleep 2.0

        # If the write failed and we\'re not killed, it probably didn\'t start
        if [[ -e $DIR/stdin ]] && kill $TEST_PID 2>/dev/null; then
            echo \'xscreen timeout\' >&2
            wait $TEST_PID 2>/dev/null

            # Send ^C to clear any half-written command (e.g. no closing braces)
            screen -S $SCREEN_NAME -p0 -X stuff $\'\\003\'

            # Write nothing to output, triggers SIGPIPE
            echo -n 1> $DIR/stdout 2> $DIR/stderr

            # Stop stdin by creating a fake reader and sending SIGPIPE
            cat $DIR/stdin >/dev/null &
            fuser -s -PIPE -k -w $DIR/stdin
        fi
    } &
    CHECKER_PID=$!

    # Start the command (Clear line ^A^K, enter command with redirects, run with ^O)
    screen -S $SCREEN_NAME -p0 -X stuff \"$(echo -ne \'\\001\\013\') { $* ; echo \\$? > $DIR/status ; } <$DIR/stdin 1> >(tee $DIR/stdout) 2> >(tee $DIR/stderr >&2)$(echo -ne \'\\015\')\"

    # Forward stdin
    cat > $DIR/stdin
    kill $CHECKER_PID 2>/dev/null && wait $CHECKER_PID 2>/dev/null

    # Just in case stdin is closed early, wait for output to finish
    wait $READER_PID 2>/dev/null

    trap - INT

    return $(cat $DIR/status)
}

if [[ -n $SERVER ]]; then
    ssh $SERVER $SERVERPORT \"$(typeset -f xscreen); xscreen $@\"
    RET=$?
    if [[ $RET == 124 ]]; then
        echo \"To start screen: ssh $SERVER $SERVERPORT \\\"screen -dmS $1\\\"\" >&2
    fi
    exit $RET
else
    xscreen \"$1\" \"${@:2}\"
fi
    

要回复问题请先登录注册