Как я могу получить подтверждение перед выходом из экрана?

Я люблю использовать curl

curl http://www.example.com/

с переменной:

page_content=`curl http://www.example.com`
echo $page_content

(размещая это отдельно, чтобы сделать возможным SO голосование).

2
11.04.2018, 13:23
3 ответа

Я подошел к этому, замаскировав команду exitфункцией; функция проверяет, находитесь ли вы в пределах экрана, и являетесь ли вы единственным дочерним процессом, оставшимся от этого экранного процесса.

exit() {
  if  [[ "$(ps -o pid= --ppid "$(ps -o ppid= -p "$$")" | wc -l)" -eq 1 ]]
  then
    read -p "Warning: you are in the last screen window; do you really want to exit? (y/n) "
    case $REPLY in
        (y*) command exit "$@" ;;
    esac
  else
    # not within screen at all, or not within the last screen window
    command exit "$@"
  fi
}

Вам нужно будет включить эту функцию в свой профиль (bash ), например. ~/.bash_profile. При запуске экрана он (, если не указано иное ), запустит экземпляр вашей $SHELL. Эта оболочка будет потомком экранного процесса. При выходе из дочерней оболочки приведенный выше код проверяет, сколько процессов являются дочерними по отношению к родительскому процессу текущей оболочки. Изнутри наружу:

  • $(ps -o ppid= -p "$$")--запрашивает родительский PID (добавление =подавляет строку заголовка )текущего процесса($$)
  • $(ps -o pid= --ppid... | wc -l)--снова запрашивает список PID (без заголовка ), чей родительский PID является нашим родителем, затем подсчитывает количество строк вывода

Если кажется, что мы являемся последним дочерним процессом сеанса экрана, он запрашивает подтверждение; если ответ начинается с буквы y, функция вызывает «настоящую» команду exitдля выхода из оболочки; в противном случае функция завершается без выхода из оболочки.

Если мы не последний дочерний процесс, функция продолжается и завершается нормально.

Пара заметок по мере разработки:

  • Первоначально у меня было больше тестов в строке if, чтобы увидеть, находимся ли мы в сеансе экрана, в том числе проверить, заполнено ли STYи SHLVLбольше 1. screen устанавливает STY, и bash будет увеличивать SHLVL, но ни одна из этих переменных не предназначена только для чтения -, поэтому проверка недостаточно надежна, чтобы быть полезной.

  • Экран
  • также устанавливает переменную WINDOW, но проверка ее на 0ненадежна; вы можете открыть два окна, а затем закрыть окно 0, оставив окно 1последним.

  • Ввод EOF (обычно Control + D)будет, по умолчанию,заставить оболочку немедленно выйти, минуя эту функцию-оболочку. Лучшим обходным решением, которое я знаю, было бы установить для переменной IGNOREEOFкакое-то ненулевое значение -; это только отсрочит неизбежный выход оболочки.

Поскольку я использовал так много специфических функций bash-(и GNU procutils -)выше, я хотел также предоставить решение, совместимое с POSIX -. Строка psизменяется на схему ps... | grep -c, чтобы зафиксировать количество процессов с определенным родительским PID. Другое изменение состоит в том, чтобы переработать -read -pв отдельную подсказку и read.

exit() {
  parent="$(ps -o ppid= -p $$)"
  if [ "$( ps -eo ppid= | grep -c "^ *${parent}\$" )" -eq 1 ]
  then
    printf "Warning: you are in the last screen window; do you really want to exit? (y/n) "
    read REPLY
    case $REPLY in
        (y*) command exit "$@" ;;
    esac
  else
    # not within screen at all, or not within the last screen window
    command exit "$@"
  fi
}
3
27.01.2020, 22:09

Я предполагаю, что вы используете bash.

are_u_sure(){
        read -n1 -p "Are you sure to exit? [y/N] "
        [ "$REPLY" != y ] && { echo; history -a; bash; }
}

trap are_u_sure EXIT

Добавьте это в свой ~/.bashrc, а затем всякий раз, когда вы пытаетесь выйти из bash (, введите exit или ^D ), вам будет предложено. И вы никогда не бросите, если не нажмете «y».

Таким образом, нам не нужно придерживаться магии экрана, так как мы можем делать это широко -.

Поскольку этот подход чрезвычайно прост, у него есть недостаток: вы потеряете присвоения переменных, которые вы ввели ранее. Но, может быть, мы сможем над этим поработать. В любом случае вы можете изменить этот код в соответствии с вашими потребностями.

0
27.01.2020, 22:09

Ни одно другое решение, которое я видел, меня не удовлетворило, поэтому я остановился на этом (, добавленном в.bashrc):

exit_with_prompt() {
    printf "Do you really want to exit screen? (y/n) "
    read REPLY
    case $REPLY in
        (y*) command exit "$@" ;;
    esac
}

export IGNOREEOF=0
[[ $(type -t exit) == "alias" ]] && unalias exit
[[ $(type -t logout) == "alias" ]] && unalias logout

if grep -q "^screen\b" /proc/$PPID/comm; then
    export IGNOREEOF=2
    alias exit=exit_with_prompt
    alias logout=exit_with_prompt
fi

А потом это в.screenrc:

shell -$SHELL

Это работает как бы в обратном направлении от того, как я обычно это делаю. Он сбрасывает псевдонимы и повторно -включает ctrl -d -> выйти в обычном режиме, но проверяет, запущен ли bash непосредственно внутри экземпляра экрана (, в частности, он проверяет, является ли запуск команды родительского процесса «экран», затем слово -граница ), затем он отключает ctrl -d/EOF для выхода и устанавливает выход с псевдонимами подсказок как для выхода, так и для выхода из системы.

Пользуюсь им не так давно, но пока вполне доволен его работой.

0
14.04.2020, 23:01

Теги

Похожие вопросы