$ @ Используется в цикле для математики

Правильный способ - использовать следующее в вашем ~ / .bashrc , как @Gilles предложил выше (здесь более короткая версия):

_my_cd () { CDPATH= _cd "$@";}

Лучше всего проверить CDPATH тогда и только тогда, когда нет совпадения обнаруживаются локально:

_my_cd () { CDPATH= _cd "$@"; if [ -z "$COMPREPLY" ]; then _cd "$@"; fi;}

Таким образом, вы получаете функциональность программируемого завершения, не доставляя неудобств. Не забывайте

complete -F _my_cd cd

По какой-то причине / usr / share / bash-Completion / bash_completion имеет -o nospace для cd (хотя nospace кажется по умолчанию), так что вы также можете иметь:

complete -F _my_cd -o nospace cd
1
06.07.2018, 18:36
5 ответов

Как правило, аргумент автоматически преобразуется в целое число, если он используется внутри арифметического $((...))расширения. Этот цикл суммирует все аргументы:

for x; do sum=$((sum+x)); done; echo "$sum"

Оболочка кэширует все аргументы в отдельных ячейках памяти, поскольку программа на языке C работает с массивом argv[]. Пользователю оболочки не нужно иметь дело непосредственно с этим массивом, оболочка помогает, назначая их $1, $2, $3 и т. д. Оболочка также абстрагирует такой список как «$@». И, наконец, синтаксис for xявляется сокращением для for x in "$@"для перебора всех аргументов.

Предполагается, что аргументы представляют собой десятичные числа, которые не начинаются с нуля, восьмеричные числа, начинающиеся с нуля, или шестнадцатеричные числа, начинающиеся с 0x, и что общая сумма не переполняется (2^63 -1 в 64-битных системах)

Этот список:

$./script 12 021 0xab

Напечатает200(десятичный результат ).

8
27.01.2020, 23:10

Возьмите аргументы один за другим:

total=0
while [ -n "$1" ]; do
  total=$((total + "$1"))
  shift
done

Или используйте цикл for:

total=0
for argument; do
  total=$((total + "$argument"))
done
3
27.01.2020, 23:10

Этого можно добиться следующим:

tr ' ' '+' <<<"$@" | bc

Он принимает все переданные аргументы и заменяет пробел знаком +, а затем передает это в bc.

8
27.01.2020, 23:10

Помимо $(()), как и в других ответах, вы также можете использовать (())и использовать +=внутри, как это:

sum=0
for x; do
  (( sum += x ))
done
echo $sum

Также может быть полезно объяснить, что вы делали в предоставленном вами коде. По сути, вы разделяете каждый аргумент на пробел (, потому что вы не удваиваете -кавычки $@в for i in $@), а затем вы перебираете результат. Затем вы проигнорировали выполненное вами присваивание и снова дважды разделили аргументы по пробелам и соединили последний аргумент первого набора и первый аргумент второго набора с помощью +, затем вызвали команду, названную первым аргументом, с помощью остальные аргументы как аргументы. Так, например, если бы этот скрипт был назван sumи вы назвали его так :sum "1 2" 3, этот $@+$@попытался бы вызвать команду 1(, даже ища/bin/1)вот так:1 "2" "3+1" "2" "3". Это, вероятно, привело бы к предупреждению bash что-то вроде bash: 1: command not found, 3 раза (по одному разу для каждого аргумента ). Затем, поскольку вы написали echoвнутри цикла, он попытается сообщить общее количество раз для каждого аргумента. На самом деле, он попытается выполнить 1 "2" "3", а 1снова интерпретируется как команда из-за обратных кавычек в строке. Это также приведет к предупреждению bash о том, что команда не найдена. Поскольку команды не было, вывода не будет, а echoпросто выведет «итого».Таким образом, полный результат:

$ sum "1 2" 3
bash: 1: command not found
bash: 1: command not found
the total is 
bash: 1: command not found
bash: 1: command not found
the total is 
bash: 1: command not found
bash: 1: command not found
the total is 
2
27.01.2020, 23:10
#!/bin/sh

IFS='+'
printf '%s\n' "$*" | bc

Тестирование

$./script.sh 1 2 3 -1 30 0.1
35.1

"$*"расширит до позиционных параметров (аргументы командной строки ), разделенные первым символом переменной оболочки IFS. Мы устанавливаем для IFSзнак плюс и передаем строку в bcдля оценки.

Если требуется только целочисленная арифметика:

#!/bin/sh

IFS='+'
printf '%d\n' "$(( $* ))"
1
27.01.2020, 23:10

Теги

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