История Bash — запомнить экранированные новые строки

#bash #readline

#bash #readline

Вопрос:

У меня есть длинные цепочки передаваемых команд, которые я хотел бы отформатировать по нескольким строкам (и отозвать для дальнейшего редактирования с помощью «fc»)

Как мне заставить историю bash запоминать экранированные новые строки, добавленные для форматирования?

Например, если я наберу:

 $ echo a b c 
>  | grep a
a b c
  

История напоминает об этом с удалением экранированной новой строки:

 $ echo a b c  | grep a
  

Я знаю, что я могу использовать shopt -s lithist для отображения новых строк, не экранированных:
Например, после запуска:

 $ shopt -s lithist
  

Приведенная ниже команда:

 $ for X in a b c; do
> echo $X
> done
a
b
c
  

вызывается как:

 $ for X in a b c; do
echo $X
done
  

Но при этом не сохраняется форматирование экранированных новых строк (которые необходимы для форматирования цепочек каналов).

Ответ №1:

Я не думаю, что то, что вы хотите, точно возможно. На справочной странице bash указано:

 If a <newline> pair appears, and the backslash is not
itself quoted, the <newline> is treated as a line continuation (that
is, it is removed from the input stream and effectively ignored).
  

Один из способов обойти это — с lithist помощью опции оболочки просто переформатировать ваш код. Итак, вместо этого:

 $ echo a b c 
>  | grep a
a b c
  

Сделайте это:

 $ echo a b c |
> grep a
  

На самом деле вам не нужно ставить в конце строки — если вы можете показать bash, что ожидается ввод, он все равно ожидает следующей строки. (Возможно, вы уже знаете это, но) это также работает для нескольких строк ввода:

 $ echo 'one
> two
> three'
one
two
three
  

Редактировать: в ответ на вопрос, заданный в комментарии ниже, о том, как возможно передать несколько параметров командной строки в отдельных строках.

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

 $ opts=(
> -s 'test'
> someone@example.com
> )
$ mutt ${opts[*]}  # launches: mutt -s someone@example.com
  

Комментарии:

1. Спасибо! Это касается большинства моих вариантов использования. Есть ли какой-нибудь трюк для использования переключателей командной строки, по одному на строку, например: mycommand —name1 —value1 —name2 —value2 …

2. Хм… Единственное, о чем я могу думать, это что-то вроде… что ж, я обновлю ответ.

3. Dern… Я бы хотел, чтобы bash не отбрасывал эту информацию для истории: ( Но пока это обходное решение кажется хорошим — спасибо!