#!/bin/bash
function0()
{
local t1=$(exit 1)
echo $t1
}
function0
echo
печатает пустое значение Я ожидал:
1
Почему t1
переменной не присваивается возвращаемое значение команды выхода - 1
?
#!/bin/bash
function0()
{
local t1=$(exit 1)
echo $t1
}
function0
echo
печатает пустое значение Я ожидал:
1
Почему t1
переменной не присваивается возвращаемое значение команды выхода - 1
?
Ответы:
local t1=$(exit 1)
говорит оболочке:
exit 1
в дольках;t1
, локальной для функции.Таким образом, это нормально, что t1
заканчивается пустым.
( $()
известен как подстановка команд .)
Код выхода всегда присваивается $?
, так что вы можете сделать
function0()
{
(exit 1)
echo "$?"
}
чтобы получить эффект, который вы ищете. Конечно, вы можете назначить $?
другую переменную:
function0()
{
(exit 1)
local t1=$?
echo "$t1"
}
$(trap 'printf "::ERRNO:$?"' 0; # now do whatever however
Код выхода был сохранен в $? переменная. Используя подстановку команд только для захвата вывода, вы должны использовать (...) для создания подоболочки :
#!/bin/bash
func() {
(exit 1)
local t1=$?
printf '%d\n' "$t1"
}
func
t1=$?
- использовать его, нет? и не $?
будет забит заданием оп? Я думаю, что спрашиваю, не должно ли это бытьprintf '%d\n' "${t1}"
В bash
этом работает:
loc(){ local "x=$(exit "$1"):$?"
printf '$%s:\t%d\n' \
x "${x##*:}" \? "$?"
}
Это связано с порядком оценки команд и назначения переменных. local
имеет собственное возвращаемое значение - и это текущая команда, а не подстановка команды. Причина такие вещи, как ...
x=$(exit 1); echo "$?"
... может вернуть 1, потому что в этой команде никогда нет возврата, за исключением запуска подоболочки для присвоения $x
значения - так$?
он не становится засоренным, как это происходит практически во всех других случаях, когда используются подстановки команд.
В любом случае, с local
этим действительно происходит заторможенность - но если вы поймаете его как раз в нужное время - то есть, пока расширения еще оцениваются и до того, local
как у подпрограмм есть шанс засорять это - вы все равно можете назначить его.
unset x; loc 130; echo "${x-\$x is unset}"
... печать ...
$x: 130
$?: 0
$x is unset
Вы должны знать, однако, что во многих оболочках вы не можете рассчитывать на то, $?
что вас поставили на среднюю оценку таким образом. На самом деле, это, вероятно, потому что эти оболочки не утруждают себя переоценкой на каждом возможном этапе, как, возможно,bash
делает - что, я бы поспорил, вероятно, лучшее поведение, чем у bash
. Вы действительно хотите, чтобы ваш интерпретатор рекурсивно оценивал значения цикла, которые, скорее всего, будут перезаписаны до того, как у вас появится возможность их использовать?
Во всяком случае, вот как вы можете это сделать.
В зависимости от того, почему вы пытаетесь просто получить код выхода, вы также можете просто запустить, if some-command; then echo "Success $?"; else echo "Failure $?"; fi
который ничего не делает с выводом команды, он просто оценивает код выхода команды run. Вы можете добавить or
(or
$ ( around the command and you'll still get the same results. A better example might be
если grep -q 'somestring' somefile; затем echo "Найден код выхода somestring равным $?"; Иначе "Не найден код выхода somestring равным $?"; Fi`.
Вы также можете проверить код возврата функции, который может быть явным return 3
или подразумеваемым кодом возврата, который является результатом последней команды, в этом случае вам нужно быть осторожным, чтобы у вас не было echo
в конце функция, в противном случае она маскирует / сбрасывает предыдущий код выхода.
command_last () {
echo "True is `true`"
echo "False is `false`"
false
}
command_last; echo $?
# Outputs:
# True is 0
# False is 1
# 1
echo_last () {
echo "True is `true`"
echo "False is `false`"
false
# echo'ing literally anything (or nothing) returns true aka exit 0
echo
}
echo_last; echo $?
# Outputs:
# True is 0
# False is 1
# # Blank line due to empty echo
# 0
Наконец, подвох, поскольку вы не можете сделать это, VAR=(SOME_COMMAND)
потому что VAR=()
это определение массива, поэтому вам нужно VAR=( $(echo 'Some value') )
.