Командные строки: использовать возвращаемое значение в качестве аргумента для другой команды [duplicate]

У меня была эта проблема, но sudo update-ca-certificates --fresh не исправил ее. Оказывается, моя версия icedtea устарела относительно моего варианта nss.

9
задан 24 April 2015 в 03:07

4 ответа

Используйте подстановку команд Bash $(), вам также нужно -o с grep, чтобы выбрать только выбранную часть:

cd "$(pip install django | grep -o '/usr.*')"

Обратите внимание, что хотя в этом случае вы уйдете, но вы всегда должны заключите подстановку команд в двойные кавычки, чтобы оболочка не выполняла подмену команды в пробелах (по умолчанию пробел, табуляция и новая строка, зависит от переменной IFS в случае bash). [ ! d2]

16
ответ дан 18 July 2018 в 10:24

Используйте подстановку команд Bash $(), вам также нужно -o с grep, чтобы выбрать только выбранную часть:

cd "$(pip install django | grep -o '/usr.*')"

Обратите внимание, что хотя в этом случае вы уйдете, но вы всегда должны заключите подстановку команд в двойные кавычки, чтобы оболочка не выполняла подмену команды в пробелах (по умолчанию пробел, табуляция и новая строка, зависит от переменной IFS в случае bash). [ ! d2]

16
ответ дан 24 July 2018 в 19:34

В зависимости от того, что вы делаете и не знаете заранее о выходе pip, вы можете выбрать grep для чего-то другого, кроме /usr.*.

Если вы знаете, что начинается каталог с /usr (и что он появляется в конце строки вывода из pip и что /usr нигде не отображается в строке перед именем каталога), то это прекрасный выбор; Ответ heemayl говорит вам, как это сделать.

Если причина, по которой вы знаете, начинается с /usr, заключается в том, что вы только что запустили команду и знаете каталог, в который хотите изменить, я предлагаю более простое решение запуска команда cd /usr/lib64/python2.7/site-packages. Это меньше набирает, даже если вы не используете завершение табуляции.

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

Если вы знаете , каталог начинается с /usr (т. Е. начинается с /), а в строке перед именем каталога нет /, вы можете использовать такое же регулярное выражение, как в ответе heemayl , но с / вместо /usr: [ ! d9] cd "$(pip install django | grep -o '/.*')"

Это соответствует a /, за которым следует ноль или больше (*) любого символа (.).

Если вы знаете и no / появляется в строке перед именем каталога (без пробелов или вкладок) и появляется в конце строки, вы можете использовать:

cd "$(pip install django | grep -oP '[^\h]+$')"

Здесь я использовал Perl regexp (-P), потому что аббревиатура \h (для [:blank:]) упрощает ввод и чтение, чем эквивалентное расширенное регулярное выражение (-E). Это соответствует одному или нескольким (+) любого символа в классе символов ([ ]), который не является (^) пробелом или вкладкой (\h).

] Если вы знаете, что t появляется в конце строки (т. Е. Заполняется как слева, так и справа пробелами) и что это единственное такое появление in на линии, вы можете использовать:

cd "$(pip install django | grep -oP '\hin\h+\K.+')"

Для использования одного или нескольких символов (.+), которые появляются после пробела или вкладки (\K), используется положительное выражение обратной связи нулевой ширины (\h), in и еще одно или несколько пробелов или вкладок (\h+) без фактического включения in и пробелов, окружающих его в матче. Perl regexp - это функция регулярных выражений Perl.

Работал бы и шаблон \h+in\h+\K.+, но нам нужно искать только пробел перед in, независимо от количества присутствующих. Напротив, мы должны сопоставить не пробелы после in, иначе они не будут отброшены \K, и они будут сопоставлены как часть имени каталога.

Если вы знаете , это единственное такое появление in в строке , вы можете использовать:

set +H cd "$(pip install django | grep -oP '\hin\h+(?!.*\hin\h.*)\K.*')" set -H

Там, положительное утверждение обратной связи с нулевой шириной (f42) )).

! появляется таким образом, что его трудно избежать изящно; метод, который я использовал, чтобы предотвратить его запуск запуска истории оболочки перед тем, как передать его в grep, - это временно отключить расширение истории (set +H) перед запуском команды и снова включить ее (set -H). Если вы используете это в скрипте, и ваш скрипт не содержит set -H, вам не нужно это делать, поскольку расширение истории включается автоматически только тогда, когда оболочка работает в интерактивном режиме.

Наконец, обратите внимание, что ни один из них, ни ответ heemayl, на самом деле не выводят вывод grep в cd (хотя вывод pip по-прежнему передается по каналу grep). Вместо каналов подходящим инструментом для этого задания является подстановка команд.

9
ответ дан 18 July 2018 в 10:24

В зависимости от того, что вы делаете и не знаете заранее о выходе pip, вы можете выбрать grep для чего-то другого, кроме /usr.*.

Если вы знаете, что начинается каталог с /usr (и что он появляется в конце строки вывода из pip и что /usr нигде не отображается в строке перед именем каталога), то это прекрасный выбор; Ответ heemayl говорит вам, как это сделать.

Если причина, по которой вы знаете, начинается с /usr, заключается в том, что вы только что запустили команду и знаете каталог, в который хотите изменить, я предлагаю более простое решение запуска команда cd /usr/lib64/python2.7/site-packages. Это меньше набирает, даже если вы не используете завершение табуляции.

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

Если вы знаете , каталог начинается с /usr (т. Е. начинается с /), а в строке перед именем каталога нет /, вы можете использовать такое же регулярное выражение, как в ответе heemayl , но с / вместо /usr: [ ! d9] cd "$(pip install django | grep -o '/.*')"

Это соответствует a /, за которым следует ноль или больше (*) любого символа (.).

Если вы знаете и no / появляется в строке перед именем каталога (без пробелов или вкладок) и появляется в конце строки, вы можете использовать:

cd "$(pip install django | grep -oP '[^\h]+$')"

Здесь я использовал Perl regexp (-P), потому что аббревиатура \h (для [:blank:]) упрощает ввод и чтение, чем эквивалентное расширенное регулярное выражение (-E). Это соответствует одному или нескольким (+) любого символа в классе символов ([ ]), который не является (^) пробелом или вкладкой (\h).

] Если вы знаете, что t появляется в конце строки (т. Е. Заполняется как слева, так и справа пробелами) и что это единственное такое появление in на линии, вы можете использовать:

cd "$(pip install django | grep -oP '\hin\h+\K.+')"

Для использования одного или нескольких символов (.+), которые появляются после пробела или вкладки (\K), используется положительное выражение обратной связи нулевой ширины (\h), in и еще одно или несколько пробелов или вкладок (\h+) без фактического включения in и пробелов, окружающих его в матче. Perl regexp - это функция регулярных выражений Perl.

Работал бы и шаблон \h+in\h+\K.+, но нам нужно искать только пробел перед in, независимо от количества присутствующих. Напротив, мы должны сопоставить не пробелы после in, иначе они не будут отброшены \K, и они будут сопоставлены как часть имени каталога.

Если вы знаете , это единственное такое появление in в строке , вы можете использовать:

set +H cd "$(pip install django | grep -oP '\hin\h+(?!.*\hin\h.*)\K.*')" set -H

Там, положительное утверждение обратной связи с нулевой шириной (f42) )).

! появляется таким образом, что его трудно избежать изящно; метод, который я использовал, чтобы предотвратить его запуск запуска истории оболочки перед тем, как передать его в grep, - это временно отключить расширение истории (set +H) перед запуском команды и снова включить ее (set -H). Если вы используете это в скрипте, и ваш скрипт не содержит set -H, вам не нужно это делать, поскольку расширение истории включается автоматически только тогда, когда оболочка работает в интерактивном режиме.

Наконец, обратите внимание, что ни один из них, ни ответ heemayl, на самом деле не выводят вывод grep в cd (хотя вывод pip по-прежнему передается по каналу grep). Вместо каналов подходящим инструментом для этого задания является подстановка команд.

9
ответ дан 24 July 2018 в 19:34
  • 1
    Конечно, если вы хотите получить technical , оболочка использует внутренний канал для чтения вывода команды. – Random832 24 April 2015 в 07:16
  • 2
    @ Random832 Хороший момент - я немного отредактировал это. Кстати, знаете ли вы, что использование труб «под капотом»? на замену команды можно положиться? Или это деталь реализации, которая потенциально может быть выполнена по-разному в другой будущей версии bash? (Конечно, на практике я понимаю, что это best способ сделать это, и, следовательно, это вряд ли будет реализовано по-другому.) – Eliah Kagan 24 April 2015 в 07:22
  • 3
    Нет, это не гарантировано, теоретически оболочка может использовать именованный файл fifo или temp, хотя для этого нет оснований. – Random832 24 April 2015 в 14:28
  • 4
    Вы уверены в расширении истории? Единственными символами, которые могут его заблокировать, являются ` and '`, и вы используете одиночные кавычки вокруг выражения grep. – muru 28 April 2015 в 05:16
  • 5
    @muru Да, он расширен. Я тоже этого не заметил, но узнал, когда я его протестировал. [F1] не цитируется с ' -кодами, так как сами кавычки ' цитируются. Сложность команды позволяет легко предсказать ее эффект, но , по-видимому, из-за порядка разложений (! является ранним) , он заканчивается, как x=foo; echo "'$x'" (- & gt; 'foo'). Удаление внешних " -кодов приведет к тому, что ! будет ' -quoted и предотвратит расширение истории, но тогда cd потерпит неудачу, если каталог имеет пробел в своем имени. – Eliah Kagan 28 April 2015 в 06:00

Другие вопросы по тегам:

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