У меня есть сценарий в файле с именем instance:
echo "hello world"
echo ${1}
И когда я запускаю этот скрипт, используя:
./instance solfish
Я получаю этот вывод:
hello world
solfish
Но когда я запустил:
echo $#
Он говорит «0». Зачем? Я не понимаю, что означает $#.
Пожалуйста, объясните это.
$# - специальная переменная в bash, которая расширяется до количества аргументов (позиционных параметров), то есть $1, $2 ..., переданных этому скрипту или оболочке в случае аргумента, непосредственно переданного в оболочку, например. в bash -c '...' .....
Это похоже на argc в C.
Возможно, это даст понять:
$ bash -c 'echo $#'
0
$ bash -c 'echo $#' _ x
1
$ bash -c 'echo $#' _ x y
2
$ bash -c 'echo $#' _ x y z
3
Заметим, что , bash -c принимает аргумент после команды, следующей за ним, начиная с 0 ($0; технически это просто bash способ позволить вам установить $0, а не аргумент действительно), поэтому _ используется здесь как заполнитель; фактическими аргументами являются x ($1), y ($2) и z ($3).
Аналогично, в вашем скрипте (если script.sh), если у вас есть:
#!/usr/bin/env bash
echo "$#"
Затем, когда вы выполните:
./script.sh foo bar
скрипт выведет 2; Аналогично,
./script.sh foo
выведет 1.
$# - специальная переменная в bash, которая расширяется до количества аргументов (позиционных параметров), то есть $1, $2 ..., переданных этому скрипту или оболочке в случае аргумента, непосредственно переданного в оболочку, например. в bash -c '...' .....
Это похоже на argc в C.
Возможно, это даст понять:
$ bash -c 'echo $#'
0
$ bash -c 'echo $#' _ x
1
$ bash -c 'echo $#' _ x y
2
$ bash -c 'echo $#' _ x y z
3
Заметим, что , bash -c принимает аргумент после команды, следующей за ним, начиная с 0 ($0; технически это просто bash способ позволить вам установить $0, а не аргумент действительно), поэтому _ используется здесь как заполнитель; фактическими аргументами являются x ($1), y ($2) и z ($3).
Аналогично, в вашем скрипте (если script.sh), если у вас есть:
#!/usr/bin/env bash
echo "$#"
Затем, когда вы выполните:
./script.sh foo bar
скрипт выведет 2; Аналогично,
./script.sh foo
выведет 1.
$# - специальная переменная в bash, которая расширяется до количества аргументов (позиционных параметров), то есть $1, $2 ..., переданных этому скрипту или оболочке в случае аргумента, непосредственно переданного в оболочку, например. в bash -c '...' .....
Это похоже на argc в C.
Возможно, это даст понять:
$ bash -c 'echo $#'
0
$ bash -c 'echo $#' _ x
1
$ bash -c 'echo $#' _ x y
2
$ bash -c 'echo $#' _ x y z
3
Заметим, что , bash -c принимает аргумент после команды, следующей за ним, начиная с 0 ($0; технически это просто bash способ позволить вам установить $0, а не аргумент действительно), поэтому _ используется здесь как заполнитель; фактическими аргументами являются x ($1), y ($2) и z ($3).
Аналогично, в вашем скрипте (если script.sh), если у вас есть:
#!/usr/bin/env bash
echo "$#"
Затем, когда вы выполните:
./script.sh foo bar
скрипт выведет 2; Аналогично,
./script.sh foo
выведет 1.
echo $# выводит количество позиционных параметров вашего скрипта.
У вас их нет, поэтому он выводит 0.
echo $# полезен внутри скрипта, а не как отдельная команда.
Если вы запускаете скрипт с некоторыми параметрами, такими как
./instance par1 par2
, то echo $#, помещенный в скрипт, выдает 2.
$# обычно используется в сценариях bash для обеспечения передачи параметра. Обычно вы проверяете параметр в начале вашего скрипта.
Например, вот фрагмент сценария, над которым я работал сегодня:
if [[ $# -ne 1 ]]; then
echo 'One argument required for file name, e.g. "Backup-2017-07-25"'
echo '.tar will automatically be added as a file extension'
exit 1
fi
Подводя итоги $# отчетов количество параметров, переданных скрипту. В вашем случае вы не передали никаких параметров, а сообщенный результат - 0.
Часто # используется в bash для подсчета количества вхождений или длины переменной.
Чтобы найти длину строки:
myvar="some string"; echo ${#myvar}
возвращает: 11
Чтобы найти количество элементов массива:
myArr=(A B C); echo ${#myArr[@]}
возвращает: 3
Чтобы найти длину первого элемента массива:
myArr=(A B C); echo ${#myArr[0]}
возвращает: 1 (Длина A, 0 - первый элемент, поскольку массивы используют индексы / индексы с нулевым основанием).
$# - это число позиционных параметров, переданных функции скрипта, оболочки или оболочки. Это связано с тем, что, хотя функция оболочки работает, позиционные параметры временно заменяются аргументами функции. Это позволяет функциям принимать и использовать свои собственные позиционные параметры.
Этот скрипт всегда печатает 3, независимо от того, сколько аргументов было передано самому скрипту, потому что "$#" в функции f расширяется до количество аргументов, переданных функции:
#!/bin/sh
f() {
echo "$#"
}
f a b c
Это важно, потому что это означает, что такой код не работает, как вы могли бы ожидать, если вы не знакомы с тем, как позиционные параметры работают в функциях оболочки :
#!/bin/sh
check_args() { # doesn't work!
if [ "$#" -ne 2 ]; then
printf '%s: error: need 2 arguments, got %d\n' "$0" "$#" >&2
exit 1
fi
}
# Maybe check some other things...
check_args
# Do other stuff...
В check_args, $# расширяется до количества аргументов, переданных самой функции, которая в этом скрипте всегда 0.
Если вы хотите, чтобы функциональность в функции оболочки, вам придется написать что-то вроде этого:
#!/bin/sh
check_args() { # works -- the caller must pass the number of arguments received
if [ "$1" -ne 2 ]; then
printf '%s: error: need 2 arguments, got %d\n' "$0" "$1" >&2
exit 1
fi
}
# Maybe check some other things...
check_args "$#"
Это работает, потому что $# расширяется вне функции и передается функции как один из ее позиционных параметров. Внутри функции $1 расширяется до первого позиционного параметра, который был передан функции оболочки, а не к скрипту, частью которого является.
Таким образом, подобно $#, специальные параметры $1 , $2 и т. д., а также $@ и $* также относятся к аргументам, переданным функции, когда они расширены в функции. Однако $0 делает вне изменением имени функции, поэтому я все еще мог использовать его для создания сообщения об ошибке качества.
$ ./check-args-demo a b c
./check-args-demo: error: need 2 arguments, got 3
Аналогично , если вы определяете одну функцию внутри другой, вы работаете с позиционными параметрами, переданными самой внутренней функции, в которой выполняется расширение:
#!/bin/sh
outer() {
inner() {
printf 'inner() got %d arguments\n' "$#"
}
printf 'outer() got %d arguments\n' "$#"
inner x y z
}
printf 'script got %d arguments\n' "$#"
outer p q
Я вызвал этот скрипт nested и (после запуска chmod +x nested) Я запустил его:
$ ./nested a
script got 1 arguments
outer() got 2 arguments
inner() got 3 arguments
Да, я знаю. «1 аргумент» является ошибкой плюрализации.
Если вы пишете скрипт, позиционные параметры вне функции будут командно- аргументы строки, переданные скрипту, если вы не изменили их.
Один общий способ их изменения - с помощью встроенного shift, который сдвигает каждый позиционный параметр слева на один, отбрасывая первый и уменьшая $# на 1:
#!/bin/sh
while [ "$#" -ne 0 ]; do
printf '%d argument(s) remaining.\nGot "%s".\n\n' "$#" "$1"
shift
done
$ ./do-shift foo bar baz # I named the script do-shift.
3 argument(s) remaining.
Got "foo".
2 argument(s) remaining.
Got "bar".
1 argument(s) remaining.
Got "baz".
Их также можно изменить с помощью встроенной функции set:
#!/bin/sh
printf '%d args: %s\n' "$#" "$*"
set foo bar baz
printf '%d args: %s\n' "$#" "$*"
$ ./set-args a b c d e # I named the script set-args.
5 args: a b c d e
3 args: foo bar baz
$# - это число позиционных параметров, переданных функции скрипта, оболочки или оболочки. Это связано с тем, что, хотя функция оболочки работает, позиционные параметры временно заменяются аргументами функции. Это позволяет функциям принимать и использовать свои собственные позиционные параметры.
Этот скрипт всегда печатает 3, независимо от того, сколько аргументов было передано самому скрипту, потому что "$#" в функции f расширяется до количество аргументов, переданных функции:
#!/bin/sh
f() {
echo "$#"
}
f a b c
Это важно, потому что это означает, что такой код не работает, как вы могли бы ожидать, если вы не знакомы с тем, как позиционные параметры работают в функциях оболочки :
#!/bin/sh
check_args() { # doesn't work!
if [ "$#" -ne 2 ]; then
printf '%s: error: need 2 arguments, got %d\n' "$0" "$#" >&2
exit 1
fi
}
# Maybe check some other things...
check_args
# Do other stuff...
В check_args, $# расширяется до количества аргументов, переданных самой функции, которая в этом скрипте всегда 0.
Если вы хотите, чтобы функциональность в функции оболочки, вам придется написать что-то вроде этого:
#!/bin/sh
check_args() { # works -- the caller must pass the number of arguments received
if [ "$1" -ne 2 ]; then
printf '%s: error: need 2 arguments, got %d\n' "$0" "$1" >&2
exit 1
fi
}
# Maybe check some other things...
check_args "$#"
Это работает, потому что $# расширяется вне функции и передается функции как один из ее позиционных параметров. Внутри функции $1 расширяется до первого позиционного параметра, который был передан функции оболочки, а не к скрипту, частью которого является.
Таким образом, подобно $#, специальные параметры $1 , $2 и т. д., а также $@ и $* также относятся к аргументам, переданным функции, когда они расширены в функции. Однако $0 делает вне изменением имени функции, поэтому я все еще мог использовать его для создания сообщения об ошибке качества.
$ ./check-args-demo a b c
./check-args-demo: error: need 2 arguments, got 3
Аналогично , если вы определяете одну функцию внутри другой, вы работаете с позиционными параметрами, переданными самой внутренней функции, в которой выполняется расширение:
#!/bin/sh
outer() {
inner() {
printf 'inner() got %d arguments\n' "$#"
}
printf 'outer() got %d arguments\n' "$#"
inner x y z
}
printf 'script got %d arguments\n' "$#"
outer p q
Я вызвал этот скрипт nested и (после запуска chmod +x nested) Я запустил его:
$ ./nested a
script got 1 arguments
outer() got 2 arguments
inner() got 3 arguments
Да, я знаю. «1 аргумент» является ошибкой плюрализации.
Если вы пишете скрипт, позиционные параметры вне функции будут командно- аргументы строки, переданные скрипту, если вы не изменили их.
Один общий способ их изменения - с помощью встроенного shift, который сдвигает каждый позиционный параметр слева на один, отбрасывая первый и уменьшая $# на 1:
#!/bin/sh
while [ "$#" -ne 0 ]; do
printf '%d argument(s) remaining.\nGot "%s".\n\n' "$#" "$1"
shift
done
$ ./do-shift foo bar baz # I named the script do-shift.
3 argument(s) remaining.
Got "foo".
2 argument(s) remaining.
Got "bar".
1 argument(s) remaining.
Got "baz".
Их также можно изменить с помощью встроенной функции set:
#!/bin/sh
printf '%d args: %s\n' "$#" "$*"
set foo bar baz
printf '%d args: %s\n' "$#" "$*"
$ ./set-args a b c d e # I named the script set-args.
5 args: a b c d e
3 args: foo bar baz
echo $# выводит количество позиционных параметров вашего скрипта.
У вас их нет, поэтому он выводит 0.
echo $# полезен внутри скрипта, а не как отдельная команда.
Если вы запускаете скрипт с некоторыми параметрами, такими как
./instance par1 par2
, то echo $#, помещенный в скрипт, выдает 2.
$# обычно используется в сценариях bash для обеспечения передачи параметра. Обычно вы проверяете параметр в начале вашего скрипта.
Например, вот фрагмент сценария, над которым я работал сегодня:
if [[ $# -ne 1 ]]; then
echo 'One argument required for file name, e.g. "Backup-2017-07-25"'
echo '.tar will automatically be added as a file extension'
exit 1
fi
Подводя итоги $# отчетов количество параметров, переданных скрипту. В вашем случае вы не передали никаких параметров, а сообщенный результат - 0.
Часто # используется в bash для подсчета количества вхождений или длины переменной.
Чтобы найти длину строки:
myvar="some string"; echo ${#myvar}
возвращает: 11
Чтобы найти количество элементов массива:
myArr=(A B C); echo ${#myArr[@]}
возвращает: 3
Чтобы найти длину первого элемента массива:
myArr=(A B C); echo ${#myArr[0]}
возвращает: 1 (Длина A, 0 - первый элемент, поскольку массивы используют индексы / индексы с нулевым основанием).
$# - это число позиционных параметров, переданных функции скрипта, оболочки или оболочки. Это связано с тем, что, хотя функция оболочки работает, позиционные параметры временно заменяются аргументами функции. Это позволяет функциям принимать и использовать свои собственные позиционные параметры.
Этот скрипт всегда печатает 3, независимо от того, сколько аргументов было передано самому скрипту, потому что "$#" в функции f расширяется до количество аргументов, переданных функции:
#!/bin/sh
f() {
echo "$#"
}
f a b c
Это важно, потому что это означает, что такой код не работает, как вы могли бы ожидать, если вы не знакомы с тем, как позиционные параметры работают в функциях оболочки :
#!/bin/sh
check_args() { # doesn't work!
if [ "$#" -ne 2 ]; then
printf '%s: error: need 2 arguments, got %d\n' "$0" "$#" >&2
exit 1
fi
}
# Maybe check some other things...
check_args
# Do other stuff...
В check_args, $# расширяется до количества аргументов, переданных самой функции, которая в этом скрипте всегда 0.
Если вы хотите, чтобы функциональность в функции оболочки, вам придется написать что-то вроде этого:
#!/bin/sh
check_args() { # works -- the caller must pass the number of arguments received
if [ "$1" -ne 2 ]; then
printf '%s: error: need 2 arguments, got %d\n' "$0" "$1" >&2
exit 1
fi
}
# Maybe check some other things...
check_args "$#"
Это работает, потому что $# расширяется вне функции и передается функции как один из ее позиционных параметров. Внутри функции $1 расширяется до первого позиционного параметра, который был передан функции оболочки, а не к скрипту, частью которого является.
Таким образом, подобно $#, специальные параметры $1 , $2 и т. д., а также $@ и $* также относятся к аргументам, переданным функции, когда они расширены в функции. Однако $0 делает вне изменением имени функции, поэтому я все еще мог использовать его для создания сообщения об ошибке качества.
$ ./check-args-demo a b c
./check-args-demo: error: need 2 arguments, got 3
Аналогично , если вы определяете одну функцию внутри другой, вы работаете с позиционными параметрами, переданными самой внутренней функции, в которой выполняется расширение:
#!/bin/sh
outer() {
inner() {
printf 'inner() got %d arguments\n' "$#"
}
printf 'outer() got %d arguments\n' "$#"
inner x y z
}
printf 'script got %d arguments\n' "$#"
outer p q
Я вызвал этот скрипт nested и (после запуска chmod +x nested) Я запустил его:
$ ./nested a
script got 1 arguments
outer() got 2 arguments
inner() got 3 arguments
Да, я знаю. «1 аргумент» является ошибкой плюрализации.
Если вы пишете скрипт, позиционные параметры вне функции будут командно- аргументы строки, переданные скрипту, если вы не изменили их.
Один общий способ их изменения - с помощью встроенного shift, который сдвигает каждый позиционный параметр слева на один, отбрасывая первый и уменьшая $# на 1:
#!/bin/sh
while [ "$#" -ne 0 ]; do
printf '%d argument(s) remaining.\nGot "%s".\n\n' "$#" "$1"
shift
done
$ ./do-shift foo bar baz # I named the script do-shift.
3 argument(s) remaining.
Got "foo".
2 argument(s) remaining.
Got "bar".
1 argument(s) remaining.
Got "baz".
Их также можно изменить с помощью встроенной функции set:
#!/bin/sh
printf '%d args: %s\n' "$#" "$*"
set foo bar baz
printf '%d args: %s\n' "$#" "$*"
$ ./set-args a b c d e # I named the script set-args.
5 args: a b c d e
3 args: foo bar baz
echo $# выводит количество позиционных параметров вашего скрипта.
У вас их нет, поэтому он выводит 0.
echo $# полезен внутри скрипта, а не как отдельная команда.
Если вы запускаете скрипт с некоторыми параметрами, такими как
./instance par1 par2
, то echo $#, помещенный в скрипт, выдает 2.
$# обычно используется в сценариях bash для обеспечения передачи параметра. Обычно вы проверяете параметр в начале вашего скрипта.
Например, вот фрагмент сценария, над которым я работал сегодня:
if [[ $# -ne 1 ]]; then
echo 'One argument required for file name, e.g. "Backup-2017-07-25"'
echo '.tar will automatically be added as a file extension'
exit 1
fi
Подводя итоги $# отчетов количество параметров, переданных скрипту. В вашем случае вы не передали никаких параметров, а сообщенный результат - 0.
Часто # используется в bash для подсчета количества вхождений или длины переменной.
Чтобы найти длину строки:
myvar="some string"; echo ${#myvar}
возвращает: 11
Чтобы найти количество элементов массива:
myArr=(A B C); echo ${#myArr[@]}
возвращает: 3
Чтобы найти длину первого элемента массива:
myArr=(A B C); echo ${#myArr[0]}
возвращает: 1 (Длина A, 0 - первый элемент, поскольку массивы используют индексы / индексы с нулевым основанием).