У меня есть довольно простой скрипт, который выглядит примерно так:
#!/bin/bash
VAR1="$1"
MOREF='sudo run command against $VAR1 | grep name | cut -c7-'
echo $MOREF
Когда я запускаю этот скрипт из командной строки и передаю ему аргументы, я не получаю никакого вывода. Однако, когда я запускаю команды, содержащиеся в $MOREF
переменной, я могу получить вывод.
Как можно взять результаты команды, которую нужно выполнить в скрипте, сохранить ее в переменной и затем вывести эту переменную на экран?
bash
shell
command-line
Джон
источник
источник
echo
переменная является бесполезным использованиеecho
, и бесполезно использование переменных.Ответы:
В дополнение к обратным галочкам
`command`
, подстановка команд может быть выполнена с помощью$(command)
или"$(command)"
, что, как мне кажется, легче читать, и допускает вложение.Quoting (
"
) имеет значение для сохранения значений многострочных переменных ; это необязательно в правой части назначения, так как разделение слов не выполняется , поэтомуOUTPUT=$(ls -1)
будет работать нормально.источник
echo
команду.${OUTPUT}foo
. Они также требуются при выполнении строковых операций над переменной, таких как${OUTPUT/foo/bar}
Правильный путь
Если вы собираетесь использовать апостроф, вам нужно
`
, а не'
. Этот символ называется «каверз» (или «серьезный акцент»).Нравится:
источник
echo
.$()
работает. Не удалось исправить, пока я не увидел эту страницу.Некоторые трюки Bash, которые я использую для установки переменных из команд
2nd Edit 2018-02-12: добавлен другой способ, найдите в нижней части этого списка долгосрочные задачи !
2018-01-25 Редактировать: добавлен пример функции (для заполнения переменных об использовании диска)
Первый простой, старый и совместимый способ
В основном совместимый, второй способ
Поскольку вложение может стать тяжелым, для этого была применена скобка
Вложенный образец:
Чтение более чем одной переменной (с Bashisms )
Если я просто хочу использовать значение:
Вы могли видеть переменную массива :
Затем:
Но я предпочитаю это:
Первая
read foo
просто пропустит строку заголовка, но только в одной команде вы заполните 7 разных переменных:Или даже:
... будет работать и с ассоциативными массивами :
read foo disk[total] disk[used] ...
Пример функции для заполнения некоторых переменных:
Примечание:
declare
строка не требуется, просто для удобства чтения.Около
sudo cmd | grep ... | cut ...
(Пожалуйста, избегайте бесполезного
cat
! Так что это всего лишь на одну вилку меньше:Все трубы (
|
) подразумевают вилки. Где должен быть запущен другой процесс, доступ к диску, вызовы библиотек и так далее.Таким образом, использование
sed
для примера ограничит подпроцесс только одним форком :И с Bashisms :
Но для многих действий, в основном над небольшими файлами, Bash может выполнить эту работу сам:
или
Идем дальше о разделении переменных ...
Посмотрите на мой ответ Как разделить строку на разделитель в Bash?
Альтернатива: сокращение числа вилок с помощью фоновых длительных задач
2-е редактирование 2018-02-12:
Для предотвращения нескольких вилок, таких как
или
Это отлично работает, но много форков работает тяжело и медленно.
И такие команды, как
date
иbc
могут сделать много операций, строка за строкой !Видеть:
Таким образом, мы могли бы использовать длительный фоновый процесс для выполнения множества заданий без необходимости инициировать новый форк для каждого запроса.
Нам просто нужны некоторые файловые дескрипторы и fifos, чтобы сделать это правильно:
(Конечно, FD
5
и6
должны быть неиспользованы!) ... Оттуда, вы можете использовать этот процесс:В функцию
newConnector
Вы можете найти мою
newConnector
функцию на GitHub.Com или на моем собственном сайте (Примечание для GitHub: на моем сайте есть два файла. Функция и демонстрация объединены в один файл, который можно получить для использования или просто запустить для демонстрации.)Образец:
Функция
myBc
позволяет использовать фоновую задачу с простым синтаксисом и для даты:Оттуда, если вы хотите завершить один из фоновых процессов, вам просто нужно закрыть его fd :
который не нужен, потому что все fd закрываются, когда основной процесс завершается.
источник
EXISTING_CONTAINER=$(docker ps -a | grep "$(echo $CONTAINER_NAME)")
было утверждение, которое я искал.echo
; Вы хотите простоgrep "$CONTAINER_NAME"
tput
качестве фоновой задачи для цветопередачи на терминале !kubectl get ns | while read -r line; do echo
$ line | grep Term | cut -d '' -f1; done
печатает для каждой$line
пустой строки, а затемbash: xxxx: command not found
. Тем не менее, я ожидаю, что это распечатывается простоxxx
Как они уже указали вам, вы должны использовать «backticks».
Предложенная альтернатива также
$(command)
работает, и ее также легче читать, но учтите, что она действительна только для Bash или KornShell (и оболочек, производных от них), поэтому, если ваши сценарии должны быть действительно переносимыми в различных системах Unix, вы должны предпочесть старая нотация.источник
$()
полностью совместим с POSIX sh, как стандартизировано более двух десятилетий назад./bin/sh
в Solaris 10 все еще не распознает$(…)
- и AFAIK, что верно и для Solaris 11./bin/sh
естьksh93
.$()
в оболочке POSIX на HP-UX уже более 10 лет.Я знаю три способа сделать это:
Функции подходят для таких задач: **
Вызовите это, сказав
func
.Также может быть найдено другое подходящее решение:
Третий напрямую использует переменные:
Вы можете получить результат третьего решения хорошим способом:
А также противным способом:
источник
"$var"
плохо$var
знаком с Bash, почему это хорошо и противно?Просто чтобы быть другим:
источник
При установке переменной убедитесь, что у вас нет пробелов до и / или после знака = . Буквально потратил час, пытаясь понять это, пробуя всевозможные решения! Это не круто.
Правильный:
Сбой с ошибкой "вещи: не найдены" или аналогичные
источник
var=value somecommand
пробегиsomecommand
сvar
в его среде , имеющей значениеvalue
. Таким образом,var= somecommand
выполняется экспортvar
в средеsomecommand
с пустым (нулевым) значением.Если вы хотите сделать это с помощью нескольких строк / нескольких команд / с, то вы можете сделать это:
Или:
Пример:
Вывод:
Используя heredoc , вы можете легко упростить задачу , разбив длинный однострочный код на многострочный. Другой пример:
источник
bash
внутри команды подстановки? Вы уже создаете подоболочку самой подстановкой команд. Если вы хотите поместить несколько команд, просто разделите их символом новой строки или точкой с запятой.output=$(echo first; echo second; ...)
'bash -c "bash -c \"bash -c ...\""'
было бы «другим»; но я не вижу в этом смысла.ssh
sudo -s
выполнение команд mysql внутри и т. Д. (Вместо bash)variable=$(bash -c 'echo "foo"; echo "bar"')
за того, чтоvariable=$(echo "foo"; echo "bar")
этот документ является всего лишь механизмом цитирования и на самом деле ничего не добавляет, кроме еще одного бесполезного осложнения.ssh -p $port $user@$domain /bin/bash <<EOF
, чтобы предотвратитьPseudo-terminal will not be allocated because stdin is not a terminal.
предупреждениеВам нужно использовать либо
$(command-here)
или
пример
источник
$()
это намного лучше, чем обратные помехи. См. В чем преимущество использования $ () вместо обратных кавычек в сценариях оболочки?Это еще один способ, который хорошо использовать с некоторыми текстовыми редакторами, которые не могут правильно выделить каждый сложный код, который вы создаете:
источник
Вы можете использовать backticks (также известный как могилы акцента) или
$()
.Подобно:
Оба имеют одинаковый эффект. Но OUTPUT = $ (x + 2) более читаемый и последний.
источник
Если команда, которую вы пытаетесь выполнить, дает сбой, она записывает вывод в поток ошибок и затем выводится на консоль.
Чтобы избежать этого, вы должны перенаправить поток ошибок:
источник
Некоторые могут найти это полезным. Целочисленные значения в подстановке переменных, где трюк использует
$(())
двойные скобки:источник
for ((...))
цикл может показаться лучшим вариантом для переменной цикла ). Кроме того, вы не должны использовать верхний регистр для ваших личных переменных.ARR=(3 2 4 1);for((N=3,M=3,COUNT=N-1;COUNT < ${#ARR[@]};ARR[COUNT]*=M,COUNT+=N)){ :;}
но я согласен с @tripleee: я не понимаю, что это там!Вот еще два способа:
Пожалуйста, помните, что в Bash очень важно пространство. Итак, если вы хотите, чтобы ваша команда выполнялась, используйте как есть, не вводя больше пробелов.
Следующие правопреемник
harshil
кL
и затем выводит егоСледующее присваивает вывод команды
tr
L2.tr
оперируется другой переменной, L1.источник
$"..."
вероятно, не делает то, что вы думаете, что делает . 2. Это уже дано в ответе Энди Лестера.echo ${L1,,}
для прекратить или прекратитьecho ${L1^^}
.