#!/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') ).