Как использовать аргументы типа $ 1 $ 2… в цикле for? [дубликат]

Вы можете использовать следующую команду для проверки создания и удаления файлов:

~/bin/notify.sh echo "hello"

из следующего скрипта, основанного на пакете inotify-tools .

#!/usr/bin/env bash
# file: bin/notify.sh <cmd>

DIR=.
ACTION=$(echo "%f_____ %e")
"$@"
while inotifywait -qre create -qre delete --format "$ACTION" $DIR
do
   "$@"
done
14
04.10.2016, 10:50
3 ответа

В любой оболочке типа Bourne это:

for arg
do printf 'Something with "%s"\n' "$arg"
done

То есть for выполняет цикл по позиционным параметрам ( $ 1 , $ 2 ...) по умолчанию (если вы не укажете часть в ... ).

Обратите внимание, что это более переносимо, чем:

for arg; do
  printf 'Something with "%s"\n' "$arg"
done

Который не был ни POSIX до выпуска стандарта 2016 года, ни Bourne (хотя работает в большинстве других Bourne-подобных оболочек, включая bash даже в режиме POSIX)

​​Или чем:

for arg in "$@"; do
  printf 'Something with "%s"\n' "$arg"
done

Что является POSIX, но не работает должным образом в оболочке Bourne или ksh88, когда $ IFS не содержит пробела, или с некоторыми версиями оболочки Bourne, когда есть без аргумента или с некоторыми оболочками (включая некоторые версии bash ), когда нет аргумента и включена опция -u .

Или, чем

for arg do
  printf 'Something with "%s"\n' "$arg"
done

, который является POSIX и Bourne, но не работает в очень старых оболочках на основе ясеня. Я лично игнорирую это и сам использую этот синтаксис, поскольку считаю его наиболее разборчивым и не ожидаю, что какой-либо из написанного мной кода когда-либо будет интерпретирован такой загадочной оболочкой.

Дополнительная информация:


Теперь, если вы хотите, чтобы $ i перебрал [1 .. $ #] и получил доступ к соответствующим элементам, вы можете выполнить:

в любой оболочке POSIX:

i=1
for arg do
  printf '%s\n' "Arg $i: $arg"
  i=$((i + 1))
done

или:

i=1
while [ "$i" -le "$#" ]; do
  eval "arg=\${$i}"
  printf '%s\n' "Arg $i: $arg"
  i=$((i + 1))
done

Или с bash

for ((i = 1; i <= $#; i++ )); do
  printf '%s\n' "Arg $i: ${!i}"
done

$ {! i} , являющимся косвенным раскрытием переменной, которое расширяется до содержимого параметра, имя которого хранится в i переменная, аналогичная zsh P флагу раскрытия параметра:

for ((i = 1; i <= $#; i++ )); do
  printf '%s\n' "Arg $i: ${(P)i}"
done

Хотя в zsh , вы также можете получить доступ к позиционным параметрам через $ argv массив (как в csh ):

for ((i = 1; i <= $#; i++ )); do
  printf '%s\n' "Arg $i: $argv[i]"
done
53
27.01.2020, 19:50

Самый простой способ

#!/bin/bash
for i
do
 echo $i
done

и запустить

./a.sh personality brave selfish

, и вот напечатать на stdout

personality
brave
selfish
2
27.01.2020, 19:50

Я бы использовал сдвиг . Этот [-n "$ 1"] означает, что пока arg-1 не пуст, продолжать цикл.

#! /bin/bash 
while [ -n "$1" ]; do
  echo "$1"
  wget "https://ssl.gstatic.com/dictionary/static/sounds/de/0/$1.mp3"
  shift
done
4
27.01.2020, 19:50

Теги

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