Переменная с кавычками & ldquo; $ () & rdquo;

Я написал этот сценарий:

#!/bin/bash
while [ true ] 
do
    currentoutput="$(lsusb)"
    if [ "$currentoutput" != "$lastoutput" ]
    then
        echo "" date and Time >> test.log
        date +%x_r >> test.log
        lastoutput="$(lsusb)"
        lsusb >> test.log
    fi
    sleep 5
done

Я новичок, пытающийся быстро учиться, и у меня возник вопрос о кавычках переменной .

Поместите переменную между $ (), я понял, но почему кавычки нужны даже в выражении if? Это сделать вложенную команду?

12
задан 12 April 2019 в 09:57

4 ответа

В currentoutput="$(lsusb)" lsusb не является переменной, это команда. Что делает этот оператор, он выполняет команду lsusb и присваивает свой вывод переменной currentoutput.

Более старый синтаксис для этого был

currentoutput=`lsusb`

, вы можете найти его во многих примерах и сценариях

Чтобы ответить на другую часть вашего вопроса, if [ ] - это просто синтаксис 115] определяется в bash. Подробнее см. В https://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html

.
0
ответ дан 12 April 2019 в 09:57

Следующая команда запускает внешнюю команду command и возвращает ее вывод.

"$(command)"

Без скобок / круглых скобок это будет искать переменную вместо выполнения команды:

"$variable"

Что касается разницы между $variable и "$variable", это становится актуальным, когда $variable содержит пробелы. При использовании "$variable" все содержимое переменной будет вставлено в одну строку, даже если содержимое содержит пробелы. При использовании $variable содержимое переменной может быть расширено до списка аргументов из нескольких аргументов.

0
ответ дан 12 April 2019 в 09:57

Для противоположности - bash рекомендует использовать [[ ... ]] над конструкцией [ ... ], чтобы избежать необходимости заключать в кавычки переменные в тесте и, следовательно, связанные с этим проблемы разбиения слов, на которые указывали другие.

[ предоставляется в bash для совместимости POSIX со сценариями, предназначенными для работы в #!/bin/sh, или сценариями, переносимыми в bash - по большей части вам следует избегать его в пользу [[. [ 117]

, например,

# With [ - quotes are needed

$ foo='one two'; bar='one two'; [ $foo = $bar ] && echo "they're equal"
-bash: [: too many arguments

$ foo='one two'; bar='one two'; [ "$foo" = "$bar" ] && echo "they're equal"                                                                                                              
they're equal

# versus [[ - quotes not needed

$ foo='one two'; bar='one two'; [[ $foo = $bar ]] && echo "they're equal"
they're equal

0
ответ дан 12 April 2019 в 09:57

Кавычки предотвращают "разделение слова". Это: ломая переменные в несколько объектов в пробельных символах (или быть более точным, в пробелах, вкладках и новых строках, как определено в значении значения по умолчанию $IFS окружите переменную).

Например,

$ var="one two"
$ howmany(){ echo $#;  }
$ howmany $var
2
$ howmany "$var"
1

Здесь мы определяем howmany функция, которая просто сообщает нам, сколько позиционных параметров дано. Как Вы видите, существует два объекта, передаваемые переменной, и с кавычками текст в переменной рассматривают как одну единицу.

Это важно для точной передачи информации. Например, если переменная содержит путь к файлу, и имя файла содержит пробелы где угодно в пути, команда, которую Вы пытаетесь выполнить, может привести к сбою или дать неточные результаты. Если мы пытались создать файл с $var переменная, touch $var создал бы два файла, но touch "$var" всего один.

То же идет для Вашего [ "$currentoutput" != "$lastoutput" ] часть. Этот конкретный тест выполняет сравнение на двух строках. Когда тестовые прогоны, [ команда должна была бы видеть 3 аргумента - текстовая строка, != оператор и другая текстовая строка. Хранение двойных кавычек предотвращает разделение слова, и [ команда видит точно те 3 аргумента. Теперь, что происходит, если переменные закрываются кавычки?

$ var="hello world"
$ foo="hi world"
$ [ $var != $foo ]
bash: [: too many arguments
$ 

Здесь, разделение слова происходит, и вместо этого [ видит две строки hello и world сопровождаемый !=, сопровождаемый двумя другими строками hi world. Ключевой пункт - то, что без двойных кавычек, содержание переменных понято как отдельные единицы, а не один целый объект.

Присвоение замены команды не требует двойных кавычек как в

var=$( df )

где Вы имеете df вывод команды, сохраненный к var. Однако это - хорошая привычка к всегда переменным двойной кавычки и замене команды $(...) если Вы действительно на самом деле не хотите, чтобы вывод рассматривался как отдельные объекты.


На ноте стороны,

while [ true ]

часть может быть

while true

[ команда, которая оценивает ее аргументы, и [ whatever ] всегда верно независимо от того, что внутри. В отличие от этого, while true использует команду true который всегда возвращает статус выхода успеха (и это точно что while потребности цикла). Различием является немного больше ясности и меньше выполненного тестирования. С другой стороны, Вы могли также использовать : вместо true

Двойные кавычки в echo "" date and Time часть могла, вероятно, быть удалена. Они просто вставляют пустую строку и добавить дополнительное пространство к выводу. Если это желаемо, не стесняйтесь сохранять их там, но в этом случае нет никакого конкретного функционального значения.

lsusb >> test.log

Эта часть могла, вероятно, быть заменена echo "$currentoutput" >> test.log. Нет никакой причины работать lsusb снова после того, как это уже было выполнено в currentoutput=$(lsusb). В случаях, где запаздывающие новые строки должны быть сохранены в выводе - каждый видел значение в выполнении команды многократно, но в случае lsusb нет никакой потребности в этом. Чем менее внешние команды Вы называете, тем лучше, потому что каждый вызов к невстроенной команде несет расходы в ЦП, использовании памяти, и время выполнения (даже при том, что команды, вероятно, предварительно загружены из памяти).


См. также:

22
ответ дан 12 April 2019 в 09:57

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

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