Как использовать $ * при отсутствии определенных входных переменных, таких как $ 1 и $ 2 в bash-скрипте?

Это зависит от того, какой формат вывода вы хотите.

apt-cache policy показывает текущие источники с приоритетом, применяемым к каждому:

~ apt-cache policy
Package files:
 100 /var/lib/dpkg/status
     release a=now
 500 http://ppa.launchpad.net/webupd8team/java/ubuntu xenial/main i386 Packages
     release v=16.04,o=LP-PPA-webupd8team-java,a=xenial,n=xenial,l=Oracle Java (JDK) 8 / 9 Installer PPA,c=main,b=i386
     origin ppa.launchpad.net
 500 http://ppa.launchpad.net/webupd8team/java/ubuntu xenial/main amd64 Packages
     release v=16.04,o=LP-PPA-webupd8team-java,a=xenial,n=xenial,l=Oracle Java (JDK) 8 / 9 Installer PPA,c=main,b=amd64
     origin ppa.launchpad.net
 500 http://ppa.launchpad.net/ubuntu-wine/ppa/ubuntu xenial/main i386 Packages
     release v=16.04,o=LP-PPA-ubuntu-wine,a=xenial,n=xenial,l=Wine Team PPA,c=main,b=i386
     origin ppa.launchpad.net
 500 http://ppa.launchpad.net/ubuntu-wine/ppa/ubuntu xenial/main amd64 Packages
     release v=16.04,o=LP-PPA-ubuntu-wine,a=xenial,n=xenial,l=Wine Team PPA,c=main,b=amd64
     origin ppa.launchpad.net
 500 http://ppa.launchpad.net/jonathonf/vim/ubuntu xenial/main i386 Packages
     release v=16.04,o=LP-PPA-jonathonf-vim,a=xenial,n=xenial,l=Vim,c=main,b=i386
     origin ppa.launchpad.net
 500 http://ppa.launchpad.net/jonathonf/vim/ubuntu xenial/main amd64 Packages
     release v=16.04,o=LP-PPA-jonathonf-vim,a=xenial,n=xenial,l=Vim,c=main,b=amd64
....

Информация здесь может быть использована в другой подходящей конфигурации, например apt preferences или конфигурации для unattended-upgrades.

Вы также можете использовать preferences :

#! /usr/bin/env python3
import aptsources.sourceslist
sources = sourcesList.SourcesList()
for source in sources:
    if not (source.disabled or source.invalid):
        print(source.line.strip())

дает выход:

deb http://jp.archive.ubuntu.com/ubuntu/ xenial main restricted
deb-src http://jp.archive.ubuntu.com/ubuntu/ xenial main restricted
deb http://jp.archive.ubuntu.com/ubuntu/ xenial-updates main restricted
deb-src http://jp.archive.ubuntu.com/ubuntu/ xenial-updates main restricted
deb http://jp.archive.ubuntu.com/ubuntu/ xenial universe
deb-src http://jp.archive.ubuntu.com/ubuntu/ xenial universe
deb http://jp.archive.ubuntu.com/ubuntu/ xenial-updates universe
deb-src http://jp.archive.ubuntu.com/ubuntu/ xenial-updates universe
deb http://jp.archive.ubuntu.com/ubuntu/ xenial multiverse
deb-src http://jp.archive.ubuntu.com/ubuntu/ xenial multiverse
deb http://jp.archive.ubuntu.com/ubuntu/ xenial-updates multiverse
deb-src http://jp.archive.ubuntu.com/ubuntu/ xenial-updates multiverse
deb http://jp.archive.ubuntu.com/ubuntu/ xenial-backports main restricted universe multiverse
deb-src http://jp.archive.ubuntu.com/ubuntu/ xenial-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu xenial-security main restricted
deb-src http://security.ubuntu.com/ubuntu xenial-security main restricted
deb http://security.ubuntu.com/ubuntu xenial-security universe
deb-src http://security.ubuntu.com/ubuntu xenial-security universe

14
задан 4 March 2018 в 20:05

9 ответов

Вы можете просто использовать расширение bash Parameter Expansion (точнее, расширение подстроки), чтобы указать диапазон, это также работает с позиционными параметрами. Для $3 ... $n это будет:

"${*:3}" # expands to "$3 $4 $5 …"
"${@:3}" # expands to "$3" "$4" "$5" …

Вы можете попробовать его следующим образом:

$ bash -c 'echo "${@:3}"' 0 1 2 3 4 5 6
3 4 5 6

Обратите внимание, что в этом примере $0 на самом деле заполненный первым аргументом 0, когда он используется в скрипте $0, вместо этого заполняется именем скрипта, который, конечно, является первым аргументом bash, а именно, что он обычно не воспринимается как таковой. Итак, здесь мы имеем $0 = 0, $1 = 1 и т. Д., А ${@:3} выбирает каждый аргумент, начинающийся с $3.

Дальнейшее чтение:

[d6 ] bash-hackers.org: Обработка позиционных параметров
25
ответ дан 22 May 2018 в 12:47

Вы можете использовать расширение bash Parameter Expansion, чтобы указать диапазон, это также работает с позиционными параметрами. Для $3 ... $n это будет:

"${@:3}" # expands to "$3" "$4" "$5" … "${*:3}" # expands to "$3 $4 $5 …"

Имейте в виду, что оба $@ и $* игнорируют первый аргумент $0. Если вы задаетесь вопросом, какой из них использовать в вашем случае: очень вероятно, что вы хотите указать $@. Не используйте $*, если вы явно не хотите, чтобы аргументы указывались отдельно.

Вы можете попробовать это следующим образом:

$ bash -c 'echo "${@:3}"' 0 1 2 3 4 5 6 3 4 5 6 $ echo 'echo "${@:3}"' >script_file $ bash script_file 0 1 2 3 4 5 6 2 3 4 5 6

Обратите внимание, что в первый пример $0 заполняется первым аргументом 0, тогда как при использовании в скрипте $0 вместо него заполняется имя скрипта, как показывает второй пример. Имя скрипта bash, конечно, очень , первый аргумент, просто, что он обычно не воспринимается как таковой - то же самое касается сценария, исполняемого и называемого «напрямую». Итак, в первом примере мы имеем $0 = 0, $1 = 1 и т. Д., А во втором - $0 = script_file, $1 = 0, $2 = 1 и т. д .; ${@:3} выбирает каждый аргумент, начинающийся с $3.

Некоторые дополнительные примеры для возможных диапазонов:

# two arguments starting with the third $ bash -c 'echo "${@:3:2}"' 0 1 2 3 4 5 6 3 4 # every argument starting with the second to last one # a negative value needs either a preceding space or parentheses $ bash -c 'echo "${@: -2}"' 0 1 2 3 4 5 6 5 6 # two arguments starting with the fifth to last one $ bash -c 'echo "${@:(-5):2}"' 0 1 2 3 4 5 6 2 3

Дальнейшее чтение:

man bash / РАСШИРЕНИЕ / Параметр Расширение bash-hackers.org: Обработка позиционных параметров TLDP Advanced Bash-Scripting Guide: Замена параметра
31
ответ дан 17 July 2018 в 19:37

Вы можете использовать расширение bash Parameter Expansion, чтобы указать диапазон, это также работает с позиционными параметрами. Для $3 ... $n это будет:

"${@:3}" # expands to "$3" "$4" "$5" … "${*:3}" # expands to "$3 $4 $5 …"

Имейте в виду, что оба $@ и $* игнорируют первый аргумент $0. Если вы задаетесь вопросом, какой из них использовать в вашем случае: очень вероятно, что вы хотите указать $@. Не используйте $*, если вы явно не хотите, чтобы аргументы указывались отдельно.

Вы можете попробовать это следующим образом:

$ bash -c 'echo "${@:3}"' 0 1 2 3 4 5 6 3 4 5 6 $ echo 'echo "${@:3}"' >script_file $ bash script_file 0 1 2 3 4 5 6 2 3 4 5 6

Обратите внимание, что в первый пример $0 заполняется первым аргументом 0, тогда как при использовании в скрипте $0 вместо него заполняется имя скрипта, как показывает второй пример. Имя скрипта bash, конечно, очень , первый аргумент, просто, что он обычно не воспринимается как таковой - то же самое касается сценария, исполняемого и называемого «напрямую». Итак, в первом примере мы имеем $0 = 0, $1 = 1 и т. Д., А во втором - $0 = script_file, $1 = 0, $2 = 1 и т. д .; ${@:3} выбирает каждый аргумент, начинающийся с $3.

Некоторые дополнительные примеры для возможных диапазонов:

# two arguments starting with the third $ bash -c 'echo "${@:3:2}"' 0 1 2 3 4 5 6 3 4 # every argument starting with the second to last one # a negative value needs either a preceding space or parentheses $ bash -c 'echo "${@: -2}"' 0 1 2 3 4 5 6 5 6 # two arguments starting with the fifth to last one $ bash -c 'echo "${@:(-5):2}"' 0 1 2 3 4 5 6 2 3

Дальнейшее чтение:

man bash / РАСШИРЕНИЕ / Параметр Расширение bash-hackers.org: Обработка позиционных параметров TLDP Advanced Bash-Scripting Guide: Замена параметра
31
ответ дан 23 July 2018 в 20:21

Вы можете использовать встроенную функцию shift:

$ help shift
shift: shift [n]
    Shift positional parameters.

    Rename the positional parameters $N+1,$N+2 ... to $1,$2 ...  If N is
    not given, it is assumed to be 1.

    Exit Status:
    Returns success unless N is negative or greater than $#.

Ex. заданный

$ cat argtest.bash 
#!/bin/bash

shift 2

echo "$*"

, тогда

$ ./argtest.bash foo bar baz bam boo
baz bam boo
24
ответ дан 22 May 2018 в 12:47
  • 1
    @Oreoplasm Я думаю, что стоит упомянуть, что подход shift сделает невозможным доступ к $1 и $2 после их смещения. В вашем скрипте вы используете $2 рядом с $variable_in_question, вам либо нужно изменить это, либо использовать подход расширения параметров. – dessert 4 March 2018 в 03:19
  • 2
    shift хорош, когда первый один или несколько аргументов являются особыми, и имеет смысл выделять их на отдельные переменные (foo="$1"; bar="$2"; или if [[ something with $1 ]];then blah blah; shift. Но ответ на dessert с неразрушающим подходом хорош в других случаях когда вы do все еще хотите получить полный список позже или когда вы используете синтаксис fancier для выделения ограниченного диапазона аргументов, а не до бесконечности, без ввода пустых аргументов в команду, если $@ doesn ' t есть много элементов. – Peter Cordes 4 March 2018 в 06:00

Как правило, вы можете скопировать позиционные параметры в массив, удалить произвольные индексы массива и затем использовать массив для расширения до тех же нужных индексов, не теряя исходных аргументов.

Например , если мне нужны все аргументы, кроме первого, четвертого и пятого:

args=( "$@" )
unset args[0] args[3] args[4]
echo "${args[@]}"

В копии индексы сдвинуты на 1, так как $0 не является частью $@. 2]

11
ответ дан 22 May 2018 в 12:47
  • 1
    Конечно, можно объединить это, например. echo "${args[@]:2}" для третьего аргумента. – dessert 4 March 2018 в 11:49

Вы можете использовать встроенную функцию shift:

$ help shift shift: shift [n] Shift positional parameters. Rename the positional parameters $N+1,$N+2 ... to $1,$2 ... If N is not given, it is assumed to be 1. Exit Status: Returns success unless N is negative or greater than $#.

Ex. заданный

$ cat argtest.bash #!/bin/bash shift 2 echo "$*"

, тогда

$ ./argtest.bash foo bar baz bam boo baz bam boo
27
ответ дан 17 July 2018 в 19:37

Как правило, вы можете скопировать позиционные параметры в массив, удалить произвольные индексы массива и затем использовать массив для расширения до тех же нужных индексов, не теряя исходных аргументов.

Например , если мне нужны все аргументы, кроме первого, четвертого и пятого:

args=( "$@" ) unset args[0] args[3] args[4] echo "${args[@]}"

В копии индексы сдвинуты на 1, так как $0 не является частью $@.

13
ответ дан 17 July 2018 в 19:37

Вы можете использовать встроенную функцию shift:

$ help shift shift: shift [n] Shift positional parameters. Rename the positional parameters $N+1,$N+2 ... to $1,$2 ... If N is not given, it is assumed to be 1. Exit Status: Returns success unless N is negative or greater than $#.

Ex. заданный

$ cat argtest.bash #!/bin/bash shift 2 echo "$*"

, тогда

$ ./argtest.bash foo bar baz bam boo baz bam boo
27
ответ дан 23 July 2018 в 20:21
  • 1
    @Oreoplasm Я думаю, что стоит упомянуть, что подход shift сделает невозможным доступ к $1 и $2 после их смещения. В вашем скрипте вы используете $2 рядом с $variable_in_question, вам либо нужно изменить это, либо использовать подход расширения параметров. – dessert 4 March 2018 в 03:19
  • 2
    shift хорош, когда первый один или несколько аргументов являются особыми, и имеет смысл выделять их на отдельные переменные (foo="$1"; bar="$2"; или if [[ something with $1 ]];then blah blah; shift. Но ответ на dessert с неразрушающим подходом хорош в других случаях когда вы do все еще хотите получить полный список позже или когда вы используете синтаксис fancier для выделения ограниченного диапазона аргументов, а не до бесконечности, без ввода пустых аргументов в команду, если $@ doesn ' t есть много элементов. – Peter Cordes 4 March 2018 в 06:00

Как правило, вы можете скопировать позиционные параметры в массив, удалить произвольные индексы массива и затем использовать массив для расширения до тех же нужных индексов, не теряя исходных аргументов.

Например , если мне нужны все аргументы, кроме первого, четвертого и пятого:

args=( "$@" ) unset args[0] args[3] args[4] echo "${args[@]}"

В копии индексы сдвинуты на 1, так как $0 не является частью $@.

13
ответ дан 23 July 2018 в 20:21
  • 1
    Конечно, можно объединить это, например. echo "${args[@]:2}" для третьего аргумента. – dessert 4 March 2018 в 11:49

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

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