Когда возможен многострочный ввод истории (aka lithist) в bash?

В справочном руководстве bash говорится:

lithist Если включено, а опция cmdhist включена, многострочные команды сохраняются в истории со встроенными символами новой строки, а не по возможности с помощью разделителей с запятой.

с этим, следовательно, мой вопрос: где / когда / как это возможно ?

Я попытался включить и протестировать эту функцию в моем GNU bash, версии 4.4.12 (1) – сделайте это:

 shopts -s cmdhist shopts -s lithist echo -n "this is a test for a ";\ echo "multiline command" 

Затем я сделал

 history | tail 

ожидая некоторого выхода, похожего на это:

 101 shopts -s cmdlist 102 shopts -s lithist 103 echo -n "this is a test for a ";\ echo "multiline command" 104 history 

но вместо этого получите следующее:

 101 shopts -s cmdlist 102 shopts -s lithist 103 echo -n "this is a test for a "; echo "multiline command" 104 history 

Очевидно, что многострочная команда (одна с историей bash 103) не была сохранена с «встроенными новостями rathar, чем с использованием разделителей с запятой» . Почему lithist здесь невозможен? Что я сделал не так?

    2 Solutions collect form web for “Когда возможен многострочный ввод истории (aka lithist) в bash?”

    A \<new line> – это не правильный способ получить <new line> в истории.

    Память

    Позволяет использовать только строки истории, поскольку они хранятся в памяти оболочки (а не на диске).

    Давайте назовем пару команд так же, как вы:

     $ echo -n "this is a test for a ";\ > echo "two line command" 

    Что было сохранено в памяти как только что написанная строка?

     $ history 2 514 echo -n "this is a test for a ";echo "two line command" 515 history 2 

    Как вы можете видеть, «продолжение строки», обратная косая черта, сопровождаемая новой строкой, была удалена.
    Как и должно (от человека баш):

    Если появляется пара \ pair, и обратная косая черта сама не цитируется, \ рассматривается как продолжение строки (то есть она удаляется из входного потока и фактически игнорируется).

    Мы можем получить новую строку, если процитировать ее:

     $ echo " A test of > a new line" A test of a new line 

    И в этот момент история будет отражать это:

     $ history 2 518 echo "A test of a new line" 519 history 2 

    Истинная многострочная команда:

    Одним из возможных примеров многострочной команды является:

     $ for a in one two > do echo "test $a" > done test one test two 

    Которая будет свернута в одну строку истории, если установлен cmdhist is set :

     $ shopt -p cmdhist lithist shopt -s cmdhist shopt -u lithist $ history 3 24 for a in one two; do echo "test $a"; done 25 shopt -p cmdhist lithist 26 history 3 

    Номера для каждой команды изменились, потому что в какой-то момент я очистил историю (в памяти) с history -c .

    Если вы отключите cmdhist, вы получите следующее:

     $ shopt -u cmdhist $ for a in one two > do echo "test $a" > done test one test two $ history 5 5 shopt -u cmdhist 6 for a in one two 7 do echo "test $a" 8 done 9 history 5 

    Каждая строка (не полная команда) будет в отдельной строке в истории.

    Даже если lithist установлен:

     $ shopt -s lithist $ for a in one two > do echo "test $a" > done test one test two $ history 5 12 shopt -s lithist 13 for a in one two 14 do echo "test $a" 15 done 16 history 5 

    Но если оба установлены:

     $ shopt -s cmdhist lithist $ for a in one two > do echo "test $a" > done $ history 5 23 history 15 24 shopt -p cmdhist lithist 25 shopt -s cmdhist lithist 26 for a in one two do echo "test $a" done 27 history 5 

    Команда for была сохранена в виде многострочной команды с символом "newlines" вместо точки с запятой ( ; ). Сравните с выше, где литист не был установлен.

    диск

    Все вышесказанное было объяснено с помощью списка команд, хранящихся в памяти оболочки. На диск не были записаны команды. Файл (default) ~/.bash_history не был изменен.

    Этот файл будет изменен при выходе из текущей оболочки. В этот момент история перезапишет файл (если histappend не установлен), или будет добавлен в противном случае.

    Если вы хотите, чтобы команды были привязаны к диску, вам необходимо установить этот набор :

     export PROMPT_COMMAND='history -a' 

    Это добавит каждую командную строку в файл в каждой новой командной строке.

    Теперь давайте займемся бизнесом с cmdhist и литистом. Это не так просто, как может показаться. Но не волнуйтесь, все будет ясно через мгновение.

    Предположим, что вы нашли время для ввода всех команд ниже (нет ярлыка, нет псевдонимов, нет функции, вам нужны фактические команды, извините).
    Чтобы сначала очистить всю историю в памяти ( history -c ) и на диске ( сделать резервную копию ) ( history -w ), а затем попробовать три раза:

    • Со значениями по умолчанию cmdhist (set) и литистом (unset).
    • С обоими наборами
    • С обеими установками
    • Установка литиста с неустановленным cmdhist не имеет смысла (вы можете проверить его).

    Список команд для выполнения:

     $ history -c ; history -w # Clear all history ( Please backup). $ shopt -s cmdhist; shopt -u lithist $ for a in one two > do echo "test $a" > done $ shopt -s cmdhist; shopt -s lithist $ for a in one two > do echo "test $a" > done $ shopt -u cmdhist; shopt -u lithist $ for a in one two > do echo "test $a" > done 

    Вы закончите с этим (в памяти):

     $ history 1 shopt -s cmdhist; shopt -u lithist 2 for a in one two; do echo "test $a"; done 3 shopt -s cmdhist; shopt -s lithist 4 for a in one two do echo "test $a" done 5 shopt -u cmdhist; shopt -u lithist 6 for a in one two 7 do echo "test $a" 8 done 9 history 

    Три многострочных команды заканчиваются следующим образом:

    • один в строке с номером 2 (одна строка, одна команда).
    • один в многострочном номере 4 (одна команда в нескольких строках)
    • один в нескольких строках от 6 до 8

    Хорошо, но что происходит в файле? скажи это alredy ….

    наконец, в файле:

    Простой, пишите в файл и кота его, чтобы увидеть это:

     $ history -w ; cat "$HISTFILE" shopt -s cmdhist; shopt -u lithist for a in one two; do echo "test $a"; done shopt -s cmdhist; shopt -s lithist for a in one two do echo "test $a" done shopt -u cmdhist; shopt -u lithist for a in one two do echo "test $a" done history history -w ; cat "$HISTFILE" 

    Нет номеров строк, только команд, нет способа сказать, где начинается многострочный цикл и где он заканчивается. Невозможно сказать, даже если есть многострочный.

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

    Существует только один разделитель (новая строка), каждая строка считывается как одна команда.

    Есть ли решение для этого, да, использовать дополнительный разделитель.
    HISTTIMEFORMAT делает это.

    HISTTIMEFORMAT

    Когда для этой переменной задано какое-то значение, время, в которое выполнялась каждая команда, сохраняется в файле как секунда с эпохи (да, всегда секунд) после символа комментария ( # ).

    Если мы установим переменную и ~/.bash_history файл ~/.bash_history , мы получим следующее:

     $ HISTTIMEFORMAT='%F' $ history -w ; cat "$HISTFILE" #1490321397 shopt -s cmdhist; shopt -u lithist #1490321397 for a in one two; do echo "test $a"; done #1490321406 shopt -s cmdhist; shopt -s lithist #1490321406 for a in one two do echo "test $a" done #1490321418 shopt -u cmdhist; shopt -u lithist #1490321418 for a in one two #1490321418 do echo "test $a" #1490321420 done #1490321429 history #1490321439 history -w ; cat "$HISTFILE" #1490321530 HISTTIMEFORMAT='%FT%T ' #1490321571 history -w ; cat "$HISTFILE" 

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

    Формат '%FT%T ' показывает время, но только при использовании команды history:

     $ history 1 2017-03-23T22:09:57 shopt -s cmdhist; shopt -u lithist 2 2017-03-23T22:09:57 for a in one two; do echo "test $a"; done 3 2017-03-23T22:10:06 shopt -s cmdhist; shopt -s lithist 4 2017-03-23T22:10:06 for a in one two do echo "test $a" done 5 2017-03-23T22:10:18 shopt -u cmdhist; shopt -u lithist 6 2017-03-23T22:10:18 for a in one two 7 2017-03-23T22:10:18 do echo "test $a" 8 2017-03-23T22:10:20 done 9 2017-03-23T22:10:29 history 10 2017-03-23T22:10:39 history -w ; cat "$HISTFILE" 11 2017-03-23T22:12:10 HISTTIMEFORMAT='%F' 12 2017-03-23T22:12:51 history -w ; cat "$HISTFILE" 13 2017-03-23T22:15:30 history 14 2017-03-23T22:16:29 HISTTIMEFORMAT='%FT%T' 15 2017-03-23T22:16:31 history 16 2017-03-23T22:16:35 HISTTIMEFORMAT='%FT%T ' 17 2017-03-23T22:16:37 history 

    Это не похоже на многострочный комманд (потому что вы избежали возврата). Если вы делаете одно с реальными доходами, есть разница.

     $ for i in /tmp/g* > do echo $i > done /tmp/gigabyte $ shopt -s lithist $ for i in /tmp/g* > do echo $i > done /tmp/gigabyte $ history [...] 517 for i in /tmp/g* ; do echo $i ; done 518 shopt -s lithist 519 for i in /tmp/g* do echo $i done 520 history 
    Interesting Posts

    Может ли несколько пользователей одновременно выполнять команды, используя tmate с отдельными курсорами в одном сеансе?

    Перенаправление портов IPTables должно быть сломанным Apache, но не было

    Является ли моя удаленная оболочка по умолчанию проблемой?

    Переключение пользователей с помощью sudo или su в сценарий оболочки

    Kmail не может отправить smtp.office365.com

    Как настроить systemd, чтобы включить простой скрипт с помощью стандартногоIO в сетевой службе

    Есть ли способ протестировать PS1 Bash Prompts перед их выполнением?

    Как создать резервную копию из символических ссылок?

    Как удалить строку, только если она указана в указанном номере строки и соответствует шаблону?

    Есть ли причина для того, чтобы ssh и sftp были настолько неинтегрированы?

    / etc / default / grub синтаксическая ошибка

    Как получить бесплатную память на AIX?

    Быстро проверьте, работают ли многие сетевые хосты

    Как получить доступ к рейд-разделам после отказа контроллера

    Добавление пользователя «ubuntu» к экземпляру Vagrant ubuntu

    Linux и Unix - лучшая ОС в мире.