1

В bash-скрипте я хочу вывести команду в конце, поэтому пользователю нужно только нажать Enter после того, как мой скрипт завершит выполнение этой команды.

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

Этот gif должен дать представление о том, о чем я говорю:

пример

Я видел такое поведение в нескольких программах, таких как hstr и qfc, и я думаю, что даже стандартный обратный поиск делает это.

Я искал в Google все, что мог придумать, но не могу найти ответ.

6 ответов6

3

Добавьте эти строки в конце вашего bash-скрипта:

MY_COMMAND="ls"
MY_PARAMS=()
read -a MY_PARAMS -p $MY_COMMAND 
exec $MY_COMMAND ${MY_PARAMS[@]}

Это предполагает, что команда, которую вы хотите выполнить, является ls, измените ее так, как вам удобно. То, что вы вводите, сохраняется в виде массива MY_PARAMS, инициализированного первой строкой; Затем команда выполняется путем повторения команды с последующим расширением переменной массива, которая означает все ее элементы. Вышеуказанное не зависит от того, сколько элементов вы передаете своей команде. Команда exec shell заменяет оболочку на данную команду, эффективно завершая ваш скрипт.

РЕДАКТИРОВАТЬ:

Если вы хотите добавить в свой сценарий все возможности редактирования команд, гораздо больше того, что может предложить read -e , вы можете сделать следующее: установить rlwrap , а затем добавить следующий код внизу вашего сценария Bash:

stty -ixon
MYINPUT=()
HISTORY=$HOME/.bash_history
MYCOMMAND="ls"
MYINPUT=$(rlwrap -H $HISTORY -P $MYCOMMAND sh -c 'read REPLY && echo $REPLY')
stty ixon
exec sh -c "${MYINPUT[@]}"

rlwrap - это программа, способная использовать все функции readline, в отличие от очень плохой опции Bash read -e . Он позволяет вам указать файл, где искать возможные дополнения (я использовал выше историю Bash, $ HOME/.bash_history, но вы можете написать свой собственный файл). Также он может быть настроен (см. Раздел inputrc в руководстве по readline), так что вы можете выбирать между редактированием в стиле Emacs и vi, и позволяет искать совпадения вперед (Ctrl+r) или назад (Ctrl+s) файл истории, редактирование команд и многое другое.

Я добавил опции stty -ixon/set ixon , потому что большинство эмуляторов терминала пересекают управляющие последовательности Ctrl+r и Ctrl+s и т.д., И это временно отключает эту функцию.

Кроме того , команда , которую вы хотите (я использовал Ls для иллюстративных целей) предварительно загружены, и могут быть выполнены как (ударяя возврат) или изменен с помощью возможностей чтения строки из rlwrap.

То, что вышеописанное не может сделать, - это отобразить список возможных совпадений, позволяя выбирать с помощью клавиатуры Это требует некоторого программирования на BASH (см. Ответ dirkt ).

1

Не полный ответ, а объяснение того, что вы видели:

Вы можете посмотреть, как это делает qfc, проверив qfc.sh. Он использует специальные функции двух оболочек: для zsh - команда zle и для bash - переменная READLINE_LINE . Кроме того, оба варианта используют функцию, которая вызывается внутри оболочки, они не просто запускают скрипт и делают эту информацию доступной при выходе.

Делать это независимо от оболочки при выходе из скрипта - интересная проблема. :-)

0

Вот короткая (уродливая?, Глючная?) реализация с примером использования / для Bash.

inline.sh:

inline () {
    stty_backup=$(stty -g)
    #I don't know why exactly, I just faced it
    stty sane
    res=$($READLINE_LINE 3>&1 >/dev/tty)
    stty $stty_backup
    READLINE_LINE=$res
    READLINE_POINT=${#READLINE_LINE}
}
#the bind is Alt-!, you can change it
bind -x '"\e!":"inline"'

hello.sh:

#!/bin/bash
echo Do you want:
echo 1 past?
echo 2 present?
echo 3 futur?

read -p "1 or 2 or 3? " r

if [ "$r" = "1" ]; then r="uptime"
elif [ "$r" = "2" ]; then r="date"
elif [ "$r" = "3" ]; then r="fortune fortunes"
else r=""
fi

echo $r >&3

Ваш сценарий должен быть достаточно умным, строка, которую вы хотите вернуть по вашему запросу, должна быть возвращена через fd 3 (см. Inline.sh).

Сейчас,

source inline.sh

тип

./hello.sh

нажмите Alt!

Конечно, вы можете использовать inline.sh в вашем bashrc.

0

Если вы используете X, инструмент xdotool может быть решением, включив в скрипт команду, такую как:

xdotool type command-line-to-display

Если новый текст смешивается с выводом скрипта, может потребоваться некоторая акробатика.

0

Временное решение:

в последней строке вашего скрипта вы можете написать что-то вроде:

PrebuildCOMMAND="ls -lrt"             # just as example
echo "That's your command "           # keep your user informed
read -e -p " " -i "$PrebuildCOMMAND"  CMDtoEXECUTE
$CMDtoEXECUTE                         # here you execute what it was answered

Примечание: я только что заметил, что это вариант (упрощенный) того, что предложено другим ответом (более полным).

0

pause?

В командной строке в Windows есть команда pause которая может сделать то, что вы хотите выполнить.

Он выводит «Нажмите любую клавишу, чтобы продолжить ...», но его вывода можно избежать с помощью pause > nul который перенаправляет свой собственный вывод в никуда, а не на экран по умолчанию

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .