Канонический ответ на этот вопрос: С сотрудничеством процесса любым механизмом это обеспечивает. Без сотрудничества процесса это невозможно. То, что процесс состоит из потоков, является внутренней деталью процесса то есть, намеренным дизайном, не выставленным за пределами процесса.
Ваш getsubstr $var0
передает 5 args функции.
Кроме того, $* и $ тестируют каждый отдельный $1$ 2 и т.д. аргумент против # шаблона.
Оценка RegEx в bash
: Я добавил некоторые примеры в конце, и btw, '*' является только специальным regex символом, когда он используется в regex контексте, т.е. при использовании = ~. В Вашем первом использовании * в ${*
, специальное использование звездочки как (psuedo) название var, который расширяется до конкатенации всего Вара: $ за $1$ 2... и т.д...
Ваше второе использование звездочки, в #*"${2}"
, означает, что "2$", которым что-либо предшествует включая ничто, должны быть подобраны против каждого, передал 1$ и т.д. аргумент отдельно/индивидуально.
Следующий сценарий может помочь с $ и $* (примером)...
#!/bin/bash
#
getsubstr() {
echo -n " ${#@} args";
[[ "$1$2$3$4$5$6" == *\ * ]] && echo " (with embedded spaces)" || echo " (no spaces)"
echo ' "${*}" '\|"${*}"\|
echo ' ${*} '\|${*}\|
echo ' "${@}" '\|"${@}"\|
echo ' ${@} '\|${@}\|
echo ' "${*#*"${2}}" '\|"${*#*"${2}"}"\|
echo ' ${*#*"${2}} '\|${*#*"${2}"}\|
echo ' "${@#*"${2}}" '\|"${@#*"${2}"}"\|
echo ' ${@#*"${2}} '\|${@#*"${2}"}\|
echo ' ${*#B} '\|${*#B}\|
echo ' "${*#B}" '\|"${*#B}"\|
echo ' ${@#B} '\|${@#B}\|
echo ' "${@#B}" '\|"${@#B}"\|
}
var0="a B c "
echo
echo -n "Passing "; getsubstr "$var0" ; echo
echo -n "Passing "; getsubstr $var0 ; echo
echo -n "Passing "; getsubstr "$var0" "$var0" ; echo
echo -n "Passing "; getsubstr $var0 $var0 ; echo
echo
exit
###################################################################
RegEx в bash
# Regex checks: "=~" uses extended regular expression
#+ Parenthesized subexpressions within the regular expression are saved
#+ in the array variable BASH_REMATCH
#+ $BASH_REMATCH / ${BASH_REMATCH[0]} is the string matching the entire regular expression.
#+ ${BASH_REMATCH[n]} is the sub string matching the nth parenthesized subexpression
[[ "abcdef" =~ (.)(.)(.) ]] && echo "# $BASH_REMATCH"
# abc
[[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[0]}"
# abc
[[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[2]}"
# b
[[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[@]}"
# abc a b c
Причина Вы видите этот тип поведения, состоит в том потому что $*
или даже $@
расширяется до всех позиционных параметров: $1
, $2
и т.д. Когда Вы пытаетесь сделать Расширение параметра (PE) на любом из тех двух специальный Вар, Вы применяете PE к каждому позиционному параметру и ни одной строке.
man bash
$ {parameter#word}
Удалите соответствие шаблону префикса. Слово расширено для создания шаблона так же, как в расширении пути. Если шаблон соответствует началу значения параметра, то результатом расширения является расширенное значение параметра с самым коротким шаблоном соответствия (#'' case) or the longest matching pattern (the
##'' случай) удаленный. Если параметр или *, операция удаления шаблона применяется к каждому позиционному параметру в свою очередь, и расширение является результирующим списком.
По существу то, что Вы делаете, является этим:
getsubstr() {
tmp=$2
for arg; do
printf "%s " ${1#*$tmp}
shift
done
}
Следующая функция работает путем установки $*
к временному var $tmp
потому что Вы теперь применяете PE к нормальной переменной однажды.
getsubstr() {
tmp=$*
echo ${tmp#*$2}
}
P.S.
Не использовать function
поскольку это не POSIX и на самом деле абсолютно ненужный, если Вы уже используете ()
после Вашего имени функции.
P.P.S
Это на самом деле не имеет никакого отношения к регулярным выражениям, а скорее шаровидным выражениям. Более официально они известны как Расширения Параметра