Відповіді:
У Баша є test
і [
оболонки.
Подвійний кронштейн , який є оболонкою ключового слова, дає додаткові функціональні можливості . Наприклад, ви можете використовувати &&
і ||
замість -a
і -o
і є регулярний оператор виразами =~
.
Крім того, у простому тесті подвійні квадратні дужки, здається, оцінюють набагато швидше, ніж одиничні.
$ time for ((i=0; i<10000000; i++)); do [[ "$i" = 1000 ]]; done
real 0m24.548s
user 0m24.337s
sys 0m0.036s
$ time for ((i=0; i<10000000; i++)); do [ "$i" = 1000 ]; done
real 0m33.478s
user 0m33.478s
sys 0m0.000s
Дужки, крім обмеження назви змінної, використовуються для розширення параметрів, щоб ви могли робити такі дії:
Обрізати вміст змінної
$ var="abcde"; echo ${var%d*}
abc
Зробіть заміни подібними до sed
$ var="abcde"; echo ${var/de/12}
abc12
Використовуйте значення за замовчуванням
$ default="hello"; unset var; echo ${var:-$default}
hello
та ще кілька
Крім того, розширення дужок створюють списки рядків, які зазвичай повторюються в циклі:
$ echo f{oo,ee,a}d
food feed fad
$ mv error.log{,.OLD}
(error.log is renamed to error.log.OLD because the brace expression
expands to "mv error.log error.log.OLD")
$ for num in {000..2}; do echo "$num"; done
000
001
002
$ echo {00..8..2}
00 02 04 06 08
$ echo {D..T..4}
D H L P T
Зауважте, що до Bash 4 не було доступно провідних функцій нуля та приросту.
Дякую gboffi, що нагадав про розширення підтяжок.
Подвійні дужки використовуються для арифметичних операцій :
((a++))
((meaning = 42))
for ((i=0; i<10; i++))
echo $((a + b + (14 * c)))
і вони дозволяють опустити знаки долара на цілі і масивні змінні та включати пробіли навколо операторів для читабельності.
Одні дужки також використовуються для індексів масиву :
array[4]="hello"
element=${array[index]}
Фігурна дужка потрібна для (більшості / всіх?) Посилань на масив праворуч.
коментар ephemient нагадав мені, що круглі дужки також використовуються для допоміжних оболонок . І що вони використовуються для створення масивів.
array=(1 2 3)
echo ${array[1]}
2
:
.
$[expression]
:; це старий, застарілий арифметичний синтаксис виразів для новішого, кращого синтаксису:$((expression))
bash
є створення послідовностей, як зазначено периферійно нижче ( stackoverflow.com/a/8552128/2749397 ) Як я хотів би трохи прокоментувати цю функцію (як ви цього не згадали ;-) Я " m, маючи на увазі використання найбільш проголошеної відповіді як транспортного засобу ... Два приклади буквальної послідовності: echo {01..12}
-> 01 02 03 04 05 06 07 08 09 10 11 12
(зверніть увагу на початковий нуль); echo {C..Q}
-> C D E F G H I J K L M N O P Q
. Основне його використання - петлі, наприклад, for cnt in {01..12} ; do ... ${cnt} ... ; done
echo {01..12..2}
-> "01 03 05 07 09 11". Дякуємо за нагадування про послідовності. Я додам це до своєї відповіді.
Одинарна дужка ( [
) зазвичай насправді викликає програму з назвою [
; man test
або man [
для отримання додаткової інформації. Приклад:
$ VARIABLE=abcdef
$ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi
yes
Подвійна дужка ( [[
) робить те ж саме (в основному), як і одна дужка, але є вбудованим басом.
$ VARIABLE=abcdef
$ if [[ $VARIABLE == 123456 ]] ; then echo yes ; else echo no ; fi
no
Параметри ( ()
) використовуються для створення підшаровок. Наприклад:
$ pwd
/home/user
$ (cd /tmp; pwd)
/tmp
$ pwd
/home/user
Як бачимо, підсфера дозволяє вам виконувати операції, не впливаючи на оточення поточної оболонки.
(a) Дужки ( {}
) використовуються для однозначної ідентифікації змінних. Приклад:
$ VARIABLE=abcdef
$ echo Variable: $VARIABLE
Variable: abcdef
$ echo Variable: $VARIABLE123456
Variable:
$ echo Variable: ${VARIABLE}123456
Variable: abcdef123456
(b) Дужки також використовуються для виконання послідовності команд у поточному контексті оболонки, наприклад
$ { date; top -b -n1 | head ; } >logfile
# 'date' and 'top' output are concatenated,
# could be useful sometimes to hunt for a top loader )
$ { date; make 2>&1; date; } | tee logfile
# now we can calculate the duration of a build from the logfile
Існує тонка синтаксична різниця ( )
, хоча (див. Посилання на bash ); по суті, точка з коми ;
після останньої команди в фігурних дужках є обов'язковою, а фігурні дужки {
, }
повинні бути оточені пробілами.
[
насправді вбудований в Bash, але він повинен діяти так, /bin/[
як на відміну від [[
вбудованого. [[
має різні функції, як більш логічні операції та різні котирування ролей. Додатково: окремі дужки також використовуються для масивів, заміщення процесів та розширених глобусів; подвійні дужки використовуються для арифметики; фігурні дужки {}
використовуються для групування команд або безлічі типів розширення параметрів або розширення дужок або розширення послідовностей. Я впевнений, що я пропустив і деякі інші вживання ...
if [ $VARIABLE == abcdef ]
- це башизм, якого, хоча це працює, - можливо, слід уникати; або явно використовуйте bash ( if [[ ...==...]]
), або дайте зрозуміти, що ви використовуєте більш традиційний умовний ( if [ "$VARIABLE" = "abcdef" ]
). Імовірно, сценарії повинні починатися максимально просто і портативно, до тих пір, поки вони дійсно не потребують функцій, характерних для bash (з тих чи інших причин). Але в будь-якому випадку, наміри повинні бути зрозумілими; "=" і "==" і "[[" і "[" працюють по-різному, і їх використання повинно бути послідовним.
[ "$var" = ".."]
замість ==
, в той час як в C було б призначити замість тестування (і досить часта причина помилок) ... чому Didn не test
використовувати ==
замість =
? хтось знає?
/usr/bin/[
не є символьним посиланням на /usr/bin/test
, і багато іншого: ці програми навіть мають кілька різних розмірів!
)
є частиною case
синтаксису оператора для закінчення рядка справи. У ньому немає скобок, що відкриваються. Це відкинуло мене з першого разу, коли я це побачив.
Кронштейни
if [ CONDITION ] Test construct
if [[ CONDITION ]] Extended test construct
Array[1]=element1 Array initialization
[a-z] Range of characters within a Regular Expression
$[ expression ] A non-standard & obsolete version of $(( expression )) [1]
[1] http://wiki.bash-hackers.org/scripting/obsolete
Фігурні дужки
${variable} Parameter substitution
${!variable} Indirect variable reference
{ command1; command2; . . . commandN; } Block of code
{string1,string2,string3,...} Brace expansion
{a..z} Extended brace expansion
{} Text replacement, after find and xargs
Круглі дужки
( command1; command2 ) Command group executed within a subshell
Array=(element1 element2 element3) Array initialization
result=$(COMMAND) Command substitution, new style
>(COMMAND) Process substitution
<(COMMAND) Process substitution
Подвійні дужки
(( var = 78 )) Integer arithmetic
var=$(( 20 + 5 )) Integer arithmetic, with variable assignment
(( var++ )) C-style variable increment
(( var-- )) C-style variable decrement
(( var0 = var1<98?9:21 )) C-style ternary operation
$(varname)
не має відношення до синтаксису bash. Це частина синтаксису Makefile .
$(varname)
не має відношення до синтаксису bash у вашому випадку.
Я просто хотів додати їх із TLDP :
~:$ echo $SHELL
/bin/bash
~:$ echo ${#SHELL}
9
~:$ ARRAY=(one two three)
~:$ echo ${#ARRAY}
3
~:$ echo ${TEST:-test}
test
~:$ echo $TEST
~:$ export TEST=a_string
~:$ echo ${TEST:-test}
a_string
~:$ echo ${TEST2:-$TEST}
a_string
~:$ echo $TEST2
~:$ echo ${TEST2:=$TEST}
a_string
~:$ echo $TEST2
a_string
~:$ export STRING="thisisaverylongname"
~:$ echo ${STRING:4}
isaverylongname
~:$ echo ${STRING:6:5}
avery
~:$ echo ${ARRAY[*]}
one two one three one four
~:$ echo ${ARRAY[*]#one}
two three four
~:$ echo ${ARRAY[*]#t}
one wo one hree one four
~:$ echo ${ARRAY[*]#t*}
one wo one hree one four
~:$ echo ${ARRAY[*]##t*}
one one one four
~:$ echo $STRING
thisisaverylongname
~:$ echo ${STRING%name}
thisisaverylong
~:$ echo ${STRING/name/string}
thisisaverylongstring
echo ${#ARRAY}
відображає три, тому що перший елемент ARRAY
містить три символи, а не тому, що він містить три елементи! Для друку використовуйте кількість елементів echo ${#ARRAY[@]}
.
${TEST:-test}
дорівнює, $TEST
якщо змінна TEST
існує, інакше вона просто повертає рядок "test". Є ще одна версія, яка робить ще більше: ${TEST:=test}
--- яка також дорівнює, $TEST
якщо TEST існує, але коли це не відбувається, вона створює змінну TEST
і присвоює значення "test", а також стає значенням всього виразу.
Різниця між тестом , [ та [[ пояснюється докладно в BashFAQ .
Щоб скоротити довгу історію: тест реалізує старий, портативний синтаксис команди. Майже у всіх оболонках (виняток становлять найдавніші снаряди Борна) [є синонімом тесту (але вимагає остаточного аргументу]). Незважаючи на те, що всі сучасні оболонки мають вбудовані реалізації [, зазвичай все ще є зовнішній виконуваний файл з таким ім'ям, наприклад / bin / [.
[[це нова вдосконалена його версія, яка є ключовим словом, а не програмою. Це сприятливо впливає на простоту використання, як показано нижче. [[розуміється KornShell та BASH (наприклад, 2.03), але не старішими POSIX або BourneShell.
І висновок:
Коли слід використовувати нову тестову команду [[і коли стару [? Якщо портативність до BourneShell викликає занепокоєння, слід використовувати старий синтаксис. Якщо, з іншого боку, сценарій вимагає BASH або KornShell, новий синтаксис набагато гнучкіший.
Для ()
визначення функції використовуються дужки :
function_name () { command1 ; command2 ; }
Ось чому вам доведеться уникати дужок навіть у параметрах команди:
$ echo (
bash: syntax error near unexpected token `newline'
$ echo \(
(
$ echo () { command echo The command echo was redefined. ; }
$ echo anything
The command echo was redefined.
unset -f echo
. Див help unset
.
Truncate the contents of a variable
$ var="abcde"; echo ${var%d*}
abc
Make substitutions similar to sed
$ var="abcde"; echo ${var/de/12}
abc12
Use a default value
$ default="hello"; unset var; echo ${var:-$default}
hello