В:
selentry=`ls -l / | sort ; ts=${PIPESTATUS[0]}`
то же самое, что и более современный:
selentry=$(ls -l / | sort ; ts=${PIPESTATUS[0]})
Код внутри $ (...)
выполняется в среде подоболочки (в случае bash
и оболочек, отличных от ksh93
, он даже запускается в другом процессе оболочки). Таким образом, любые изменения, внесенные в переменные в этой подоболочке, не повлияют на родительскую оболочку.
Когда вы делаете:
var=$(cmd)
Однако статус выхода cmd
становится доступным в $?
.Это не распространяется на $ PIPESTATUS
, который в случае:
var=$(foo | bar)
содержит только одно значение (код выхода подоболочки, который здесь будет статусом выхода bar
( если не включена опция pipefail
, в этом случае это может быть статус выхода foo
, если он не равен нулю). Еще хуже в zsh
, где массив $ pipestatus
не зависит от команд присваивания.
Здесь, однако, если вас не заботит статус выхода sort
(подоболочки), вы можете сделать:
selentry=$(ls -l / | sort; exit "${PIPESTATUS[0]}")
ts=$?
Здесь вы также можете сделать:
exec 3< <(ls -l /) # here ls is started as an asynchronous command
ls_pid=$!
selentry=$(sort <&3)
sort_status=$?
wait "$ls_pid"
exec 3<&- # close that fd 3
ls_status=$?
Или даже:
{
selentry=$(sort)
sort_status=$?
wait "$!"
ls_status=$?
} < <(ls -l /)
Что касается более общего вопроса о том, что присвоения переменных сохраняются после подстановок команд, в ksh93
вы можете использовать $ { cmd;}
форма подстановки команд (хотя ksh93
не поддерживает $ PIPESTATUS
/ $ pipestatus
).
var=${
foo; c1=$?
bar; c2=$?
}
В других случаях аналога нет). Снаряды типа Борна, вам нужно будет данные через какое-то другое средство, например временный файл:
var=$(
foo; echo "c1=$?" > "$tempfile"
bar; echo "c2=$?" >> "$tempfile"
)
. "$tempfile"
Или здесь:
selentry=$(
ls -l / | sort
typeset -p PIPESTATUS | sed '1s/PIPESTATUS/my_&/' > "$tempfile"
}
. "$tempfile"
ls_status=${my_PIPESTATUS[0]}
Сделайте следующее:
xb@dnxb:~/tmp$ shopt interactive_comments
interactive_comments on
xb@dnxb:~/tmp$ shopt -u interactive_comments
xb@dnxb:~/tmp$ shopt interactive_comments
interactive_comments off
xb@dnxb:~/tmp$ alias #='ls -la'
xb@dnxb:~/tmp$ # /tmp -d
drwxrwxrwt 14 root root 32768 Nov 2 03:09 /tmp
xb@dnxb:~/tmp$
В ~ / .bash_aliases, экранируйте его:
shopt -u interactive_comments
alias \#='ls -la'