Как я могу показать результаты после того, как Bash прочитает одну полную строку ввода, но перед выполнением любой из команд в этой строке?

Если кто-то может придумать лучший ответ, сделайте это, но лучшее, что я нашел, было следующим: http://manuals.gfi.com/en/kerio/connect/content/server-configuration/ssl-certificates/adding-trusted-root-certificates-to-the-server-1605.html

I нашел на моем рабочем столе Ubuntu, что /usr/share/ca-certificatesявляется основным местом для сертификатов, но тот, который я искал, находился в /usr/local/share/ca-certificates. Я нашел его, используя find -iname "**"и выполнив поиск имени, совпадающего с именем родительского хоста в моей цепочке ключей.

Я также обнаружил, что в то время как Chrome на моем рабочем столе распознавал сертификат как действительный, некоторые инструменты cli (включая openssl) этого не делали.Поэтому я нашел ссылку в наших документах на эту команду для добавления в libnss, что, по-видимому, является тем, что chrome использует в качестве центра сертификации

certutil -d sql:${HOME}/.pki/nssdb/ -A -t "C,," \
         -n "" \
         -i /usr/local/share/ca-certificates/.crt

. Вышеприведенная ссылка на gfi включает некоторые действительно полезные сведения об управлении сертификатами ca в Ubuntu. / центос. Это материал, который я списал для нашей внутренней вики: -

Linux (Ubuntu, Debian)

Добавить

  1. Скопируйте ваш ЦС в каталог /usr/local/share/ca-certificates/
  2. Используйте команду: sudo cp foo.crt /usr/local/share/ca-certificates/foo.crt
  3. Обновите хранилище ЦС: sudo update-ca-certificates

Удалить

  1. Удалите свой ЦС.
  2. Обновите хранилище ЦС: sudo update-ca-certificates --fresh

Linux (CentOs 6)

Добавить

  1. Установите пакет ca-certificates: yum install ca-certificates
  2. Включите функцию динамической конфигурации ЦС: update-ca-trust force-enable
  3. Добавьте его как новый файл в /etc/pki/ca-trust/source/anchors/: cp foo.crt /etc/pki/ca-trust/source/anchors/
  4. Используйте команду: update-ca-trust Extract

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

1
04.08.2017, 18:41
3 ответа

Хороший способ понять это — взглянуть на этот пример:https://stackoverflow.com/questions/38526612/bash-unable-to-set-and-use-alias-in-the-same-line

Например, вы хотите выполнить следующую команду:

$ alias foo="echo bac" ; foo;
-bash: foo: command not found
$ foo
bac

Теперь bash будет читать всю строку, а так как fooне является псевдонимом, он не будет расширяться (псевдонимы расширяются при чтении ). Теперь при выполнении строки он установит псевдоним и выдаст ошибку.

3
27.01.2020, 23:13

Часть руководства Bash, которую вы процитировали, говорит о

Aliases are expanded when a command is read, not when it is executed. Therefore, an alias definition appearing on the same line as another command does not take effect until the next line of input is read.

Таким образом, псевдонимы на самом деле являются одним из тех примеров, которые показывают разницу между чтением и выполнением строки!

Чтобы пояснить, вот составная команда. Сначала мы пытаемся определить псевдоним, а затем пытаемся его использовать :

.

alias echo=uname; echo

Кто-то, кто не знаком с Bash, может ожидать, что вывод этой команды будетLinux(или любой другой ОС, которую вы используете ), но на самом деле она просто ничего не выводит. Это связано с тем, что Bash сначала читает строку и применяет определения псевдонимов. Вот что видит Баш:

alias echo=uname; echo

Обратите внимание, что второй echoне преобразуется в uname. Это потому, что Bash еще не выполнил нашу команду alias echo=uname, он только прочитал ее . После того, как Bash прочитал строку, он выполняет то, что прочитал. Поэтому он выполняет:

alias echo=uname; echo(это именно то, что он читал, как описано выше)

Мы даже можем проверить, выполнил ли Bash команду, набрав echo. Поскольку ранее мы определили псевдоним, echoтеперь будет преобразовано в unameво время шага чтения, поэтому Bash выполнит uname.

Короче:

$ alias echo=uname; echo

$ echo
Linux

Редактировать:

После редактирования вы спросили, есть ли способ отобразить результаты после того, как Bash прочитает одну строку ввода, но до их фактического выполнения. Ответ - да,но это не очень удобно для -повседневного использования (однако, безусловно, полезно для понимания того, что происходит внутри оболочки ).

Создайте файл со следующим содержимым:

#!/bin/bash
shopt -s expand_aliases
trapped() {
    echo "On line ${1}, Bash sees: $BASH_COMMAND"
}
trap 'trapped ${LINENO}' DEBUG
alias echo=uname; echo
echo

Затем запустите этот файл.

Вот объяснение того, как работает этот скрипт:

  • shopt -s expand_aliasesуказывает Bash расширять псевдонимы, даже если он находится в неинтерактивном режиме (, как в этом случае)
  • Затем мы определяем функцию trapped(). При вызове эта функция напечатает выполняемую в данный момент команду (вместе с номером строки, который передается как параметр ).
  • Звоним trap 'trapped ${LINENO}' DEBUG. Это сообщает Bash: «Всякий раз, когда вы видите сигнал с именем DEBUG, сначала выполните trapped ${LINENO}. DEBUG— это сигнал, автоматически генерируемый Bash перед любым выполнением простой команды . Другими словами, перед выполнением любой команды вызывается наша функция trapped().
  • Наконец, мы выполняем несколько команд для демонстрации. Однако, поскольку у нас есть ловушка, trapped()выполняется до того, как произойдет что-либо еще, поэтому Bash печатает то, что должно быть выполнено. Переменная LINENO— это просто встроенная в Bash -, которая дает нам текущий номер строки.

Если вы хотите иметь возможность «запускать» команды, вообще не выполняя их, и по-прежнему видеть, что читает Bash, вы можете изучить параметр extdebugв руководстве Bash.

2
27.01.2020, 23:13

Ваш вопрос не кристально ясен, но ваше сопоставление предложений

Aliases are expanded when a command is read, not when it is executed.

и

Bash always reads at least one complete line of input before executing any of the commands on that line.

предполагает, что в центре внимания вашего вопроса находится расширение псевдонима. (Я говорю «предполагает», потому что, помимо выдержки из руководства Bash, в вашем вопросе вообще не упоминаются псевдонимы.)

Первоначальная версия вашего вопроса

How can I show that Bash always reads at least one complete line of input before executing any of the commands on that line?

Единственный реальный способ сделать это заключается в использовании какого-либо инструмента отладки / мониторинга / трассировки изучить внутреннее состояние оболочки. Это несколько непрактично. Ответ PawkyPenguin показывает подход к тому, чтобы приводить -сомнительные аргументы в поддержку того, что говорится в руководстве. Вот вариант их ответа, который (ИМО )немного яснее:

$ alias myalias=date

$ alias myalias="ls -ld"; myalias
Fri, Aug 04, 2017  3:33:33 AM

Мы можем утверждать, что оболочка должна полностью прочитать (вторую )полную строку прежде чем он начал выполнять его потому что, когда он выполнил myalias, он выполнил его как date. К моменту выполнения псевдонима myaliasон был переопределен как ls -ld. Следовательно, оболочка должна была расшириться с myaliasна date. перед выполнением

alias myalias="ls -ld"

, поэтому она должна прочитать всю строку ввода перед выполнением любой из команд в этой строке.


Ваш измененный вопрос,

How can I show the results after Bash reads one complete line of input but before executing any of the commands on that line?

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

alias myalias="ls -ld"; date

Насколько я знаю, нет никакого способа получить этот вывод — развернута полная строка с псевдонимами. Но вариантxtrace(-x)подходит близко.

$ set -x

$ alias myalias=date
+ alias myalias=date

$ alias myalias="ls -ld"; myalias
+ alias 'myalias=ls -ld'
+ date                                                         ← The expansion of the alias
Fri, Aug 04, 2017  3:33:42 AM

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

$ animal=cat
+ animal=cat

$ echo Hello; echo world; myalias "$animal" R*
+ echo Hello
Hello
+ echo world
world
+ ls -ld cat README                                            ← The expansion of the alias
ls: cannot access cat: No such file or directory
-rw-r--r-- 2 myusername  mygroupname  489 Feb 22  2015 README

Мы не увидим ls -ld "$animal" R*; мы видим это только после расширения переменной и пути (glob ). Он также не «хорошо работает» с конвейерами :

.
$ alias myalias=date
+ alias myalias=date

$ myalias | od -cb
+ date                                                         ← The expansion of the alias
+ od -cb
0000000   F   r   i  ,       A   u   g       0   4  ,       2   0   1
        106 162 151 054 040 101 165 147 040 060 064 054 040 062 060 061
0000020   7           9   :   4   2   :   1   7       P   M  \n
        067 040 040 071 072 064 062 072 061 067 040 120 115 012
0000036

, где вывод трассировки показывает нам dateи od -cbв двух отдельных строках. (Вам нужно посмотреть исходную командную строку выяснить, что он делает date | od -cb, если это не было очевидно из вывода.)

2
27.01.2020, 23:13

Теги

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