Yanıtlar:
Bölüm 2.9.1 Açık Grup Tabanı Spesifikasyonlarının Basit Komutları bölümünde (POSIX için) belgelenmiştir . Orada bir metin duvarı var; Dikkatinizi son paragrafa yönlendiriyorum:
Bir komut adı varsa, yürütme, Komut Arama ve Yürütme bölümünde açıklandığı gibi devam edecektir . Komut adı yoksa, ancak komut bir komut değiştirme içeriyorsa, komut, gerçekleştirilen son komut değiştirme işleminin çıkış durumu ile tamamlanır. Aksi takdirde, komut sıfır çıkış durumuyla tamamlanmalıdır.
Yani mesela,
Command Exit Status
$ FOO=BAR 0 (but see also the note from icarus, below)
$ FOO=$(bar) Exit status from "bar"
$ FOO=$(bar) baz Exit status from "baz"
$ foo $(bar) Exit status from "foo"
Bash de böyle çalışır. Ancak sondaki “o kadar basit değil” bölümüne de bakın.
phk , sorusunda Ödevler komut değiştirme dışında bir çıkış durumu olan komutlar gibidir? , öneriyor
… Bir ödevin kendisi sıfır çıkış değeri olan bir komut olarak sayılır, ancak ödevin sağ tarafından uygulanmadan önce görünür (örn. Bir komut değiştirme çağrısı…)
Bu ona bakmak için korkunç bir yol değil. Basit bir komutun geri durumunu belirlemek için bir ham düzeni (bir içermeyen ;
, &
, |
, &&
ya da ||
) aşağıdaki gibidir:
$(…)
komuttan çıkış durumunu alın.Satırın dönüş durumu, karşılaştığınız son sayıdır.
Komuta bağımsız değişkenler olarak komut ikameleri , örneğin foo $(bar)
sayılmaz; çıkış durumunu alırsınız foo
. Phk gösterimini yorumlamak için , buradaki davranış
temporary_variable = EXECUTE( "bar" )
overall_exit_status = EXECUTE( "foo", temporary_variable )
Ama bu hafif bir aşırı basitleştirme. Genel iade durumu
A = $ ( cmd 1 ) B = $ ( cmd 2 ) C = $ ( cmd 3 ) D = $ ( cmd 4 ) E = mc 2, çıkış durumudur . Sonra gerçekleşir atama atama 0'a genel çıkış durumu belirlemez.
cmd4
E=
D=
Icarus , içinde PHK sorusuna verdiği cevap , önemli bir noktayı gündeme getiriyor: değişkenler salt okunur olarak ayarlanabilir. POSIX standardının 2.9.1 Bölümündeki üçüncü-son paragraf diyor ki:
Değişken atamalarından herhangi biri, geçerli kabuk ortamında salt okunur özniteliğin ayarlandığı bir değişkene bir değer atamaya çalışırsa (atamanın bu ortamda yapılıp yapılmadığına bakılmaksızın), değişken atama hatası oluşacaktır. Bu hataların sonuçları için Kabuk Hatalarının Sonuçları bölümüne bakın .
yani diyorsan
readonly A
C=Garfield A=Felix T=Tigger
Dönüş durumu 1'dir önemi olmaksızın eğer dizeleri Garfield
, Felix
ve / veya Tigger
komut ikamesi (s) ile değiştirilir - ama aşağıdaki notlara bakın.
Bölüm 2.8.1 Kabuk Hatalarının Sonuçları başka bir metin grubuna ve bir tabloya sahiptir ve
Etkileşimli bir kabuğun çıkmaması gereken tabloda gösterilen tüm durumlarda, kabuk, hatanın oluştuğu komutun başka bir işlemini gerçekleştirmemelidir.
Bazı detaylar mantıklı; bazıları şunları yapmaz:
A=
Atama bazen iptal o son cümle belirtmek için göründüğü gibi, komut satırı. Yukarıdaki örnekte, C
ayarlanmıştır Garfield
, ancak T
ayarlanmamıştır (ve elbette ikisi de ayarlanmamıştır A
).C=$(cmd1) A=$(cmd2) T=$(cmd3)
cmd1
cmd3
cmd2
Bash versiyonlarımda,
salt okunur A C = bir şey A = bir şey T = bir şey cmd 0
yok yürütmek. Özellikle,cmd0
C = $ ( cmd 1 ) A = $ ( cmd 2 ) T = $ ( cmd 3 ) cmd 0yürütür ve ancak . (Komut olmadığında bunun davranışının tersi olduğuna dikkat edin.) Ve, (yanı sıra ) ortamında da ayarlar . Bunun bash'da bir hata olup olmadığını merak ediyorum.
cmd1
cmd3
cmd2
T
C
cmd0
Bu cevabın ilk paragrafı “basit komutlar” ile ilgilidir. Spesifikasyon diyor ki,
"Basit komut", herhangi bir sırada isteğe bağlı olarak değişken atamaları ve yeniden yönlendirmelerden oluşan bir dizidir ve isteğe bağlı olarak bir denetim operatörü tarafından sonlandırılan kelimeler ve yeniden yönlendirmeler gelir.
Bunlar benim ilk örnek bloğumdakiler gibi ifadelerdir:
$ FOO=BAR
$ FOO=$(bar)
$ FOO=$(bar) baz
$ foo $(bar)
bunların ilk üçü değişken atamaları içerir ve son üçü komut ikamelerini içerir.
Ancak bazı değişken atamalar o kadar basit değildir. bash (1) diyor ki,
Atama ifadeleri de argüman olarak görünebilir
alias
,declare
,typeset
,export
,readonly
, velocal
komutları (yerleşik beyan komutları).
İçin export
, POSIX şartname diyor
ÇIKIŞ DURUMU
0
Tüm ad işlenenleri başarıyla dışa aktarıldı.
> 0En az bir ad dışa aktarılamadı veya
-p
seçenek belirtildi ve bir hata oluştu.
POSIX desteklemiyor local
, ancak bash (1) diyor ki,
local
Bir işlev içinde değilken kullanmak bir hatadır .local
Bir işlevin dışında kullanılmadığı, geçersiz bir ad girilmediği veya ad salt okunur bir değişken olmadığı sürece dönüş durumu 0'dır .
Satır aralarını okurken, bildirim komutlarının
export FOO=$(bar)
ve
local FOO=$(bar)
daha çok benziyor
foo $(bar)
onlar dan çıkış durumu görmezden sürece bar
ve size ana komuta dayalı bir çıkış durumunu vermek ( export
, local
veya foo
). Yani tuhaflığımız var
Command Exit Status
$ FOO=$(bar) Exit status from "bar"
(unless FOO is readonly)
$ export FOO=$(bar) 0 (unless FOO is readonly,
or other error from “export”)
$ local FOO=$(bar) 0 (unless FOO is readonly,
statement is not in a function,
or other error from “local”)
hangi ile gösterebiliriz
$ export FRIDAY=$(date -d tomorrow)
$ echo "FRIDAY = $FRIDAY, status = $?"
FRIDAY = Fri, May 04, 2018 8:58:30 PM, status = 0
$ export SATURDAY=$(date -d "day after tomorrow")
date: invalid date ‘day after tomorrow’
$ echo "SATURDAY = $SATURDAY, status = $?"
SATURDAY = , status = 0
ve
myfunc() {
local x=$(echo "Foo"; true); echo "x = $x -> $?"
local y=$(echo "Bar"; false); echo "y = $y -> $?"
echo -n "BUT! "
local z; z=$(echo "Baz"; false); echo "z = $z -> $?"
}
$ myfunc
x = Foo -> 0
y = Bar -> 0
BUT! z = Baz -> 1
Neyse ki ShellCheck hatayı yakalar ve SC2155'i yükseltir ;
export foo="$(mycmd)"
olarak değiştirilmeli
foo=$(mycmd)
export foo
ve
local foo="$(mycmd)"
olarak değiştirilmeli
local foo
foo=$(mycmd)
FOO=$(bar)
) teorik olarak hem çıkış durumunun hem de atamanın bir rol oynayabileceğini belirtmek gerekir
A=foo cmd
çalışır mı? cmd
A
A
salt okunur, komut C=value₁ A=value₂ T=value₃
setleri C
ancak T
(ve tabii ki A
ayarlı değil) - kabuk yok sayarak komut satırı işleme sonlandırılmış T=value₃
, çünkü A=value₂
bir hatadır. (2) Yığın Taşması sorusuna bağlantı için teşekkürler - Ben bunun üzerine yorum geldim.
local=$(false)
çıkış değeri vardır 0
çünkü (erkek sayfasından): It is an error to use local when not within a function. The return status is 0 unless local is used outside a function, an invalid name is supplied, or name is a readonly variable.
. Bu, onu bu şekilde tasarlayan dahi için dünya üzerinde yeterli trollface değildir.
Bash ( LESS=+/'^SIMPLE COMMAND EXPANSION' bash
) içinde belgelenmiştir :
Genişletmeden sonra bir komut adı kalırsa .... Aksi takdirde komut çıkar. ... Komut ikamesi yoksa, komut sıfır durumundan çıkar.
Başka bir deyişle (kelimelerim):
Genişletmeden sonra komut adı kalmadıysa ve komut yerine başka bir işlem yapılmadıysa, komut satırı sıfır durumundan çıkar.
local
bağ olduğunu biliyor musunuz ? Örneğinlocal foo=$(bar)
?