Etkileşimli bir kabuk etkileşimli olmayabilir veya tersi olabilir mi?
Not: "İnteraktif ve interaktif olmayanlar arasındaki fark nedir?" Temel sorusu hakkında çok fazla araştırma yaptım ve araştırmamın sonuçları beni bu soruyu sormaya yöneltti.
Bu sorunun kısmen uzun bir önsözü vardır, çünkü cevaplamak için "interaktif" için ne tür bir tanım kullandığımız çok önemlidir . Bir tanım, belirli bir küme için rastgele bir etiket olabilir; çeşitli özellikleri tanımlayıcı olabilir; veya size davranışı tahmin etmek ve amacı anlamak için kullanabileceğiniz bilgiler verebilir . Bu son türe "eylem tanımı" veya "dinamik tanım" diyebiliriz ve en faydalı olanıdır.
'De man 1p sh
, aşağıdaki etkileşimli kabuğun tanımı verilmiştir:
If the -i option is present, or if there are no operands and the shell’s standard input and standard error are attached to a terminal, the shell is considered to be interactive.
"-İ seçeneği" ifadesinden ve "işlenenler" kelimesinin kullanılmasından bu, çalışan bir kabukta incelenebilecek niteliklerden değil , bir kabuğun çağrılması anlamına gelir.
Bash man sayfası bunu biraz farklı ifade eder:
An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option. PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state.
İlk cümledeki tanım yine sadece bir kabuğun başlangıcını ifade eder .
İkinci cümle (okumamda) , kabuğun "etkileşimli" yapması olarak tanımlanan belirli yollarla başlatılıp başlatılmadığını belirlemek için vekil olarak kullanılan koşulları tanımlar .
O Not ben do not olarak bu cümleyi yorumlamak: "Bir bash kabuk eğer etkileşimli ve ancak $-
. 'İ' içeren" etkileşimli $-
bir tanım değil, sadece kullanışlı bir gösterge gibi görünüyor . Bu benim sorumla çok ilgili.
Bunların her ikisi de (POSIX sh
tanımı ve Bash), "interaktif" etiketinin hangi koşullarda başlattığınız bir kabuk için geçerli olduğunu belirten mekanik tanımlardır. Bu etiketin herhangi bir anlamını vermedikleri için eylem tanımları değildirler .
Ancak, Bash man sayfasının geri kalanında, "etkileşimli bir kabuk olmadıkça" veya "yalnızca etkileşimli kabuklarda veya _____ seçeneği ayarlanmışsa" belirli şekillerde davranan kabuğa atılan referanslar olduğunu görüyorum. (Çok sayıda örnek var ve bu sorunun ana konusu bu değil.)
Bu yüzden "interaktif" in, man sayfasının geri kalanında açıklanan varsayılan "interaktif" davranışların (seçenek ayarları) toplanması için uygun bir etiket olduğunu kabul edeceğim. Bu kendi içinde temel bir terim ya da nesne değildir; kabuğun kaynak kodunun dışında yetkili bir tanımı yoktur. (Örneğin, çekirdeğin tasarımında yerleşik soyutlamaları ifade eden "açık dosya tanımlayıcı" veya "durdurulmuş işlem" terimlerinin aksine).
(POSIX tanımında da tanımlanmış olsa da sh
, bu man sayfasının [ man 1p sh
] "kabuk etkileşimli olmadıkça" ve benzer ifadelerden çok daha az kullanımı man bash
vardır ve neredeyse tamamen çağırma zamanı farklılıklarına odaklanır, bu yüzden Bash'a odaklanacağım bu noktadan itibaren.)
Bir kabuğun "etkileşimli" olmasının bazı etkileri, yalnızca diğer komutları okumadan önce hangi dosyaların kabuk tarafından kaynaklandığı gibi çağırma zamanında ilişkilidir . Ancak, orada olan herhangi bir zamanda alakalı (en azından Bash) etkileri. Bu nedenle, herhangi bir çalışan kabuk için etkileşimli olup olmadığını anlamanın bir yolu olmalıdır .
Çalıştırma set +i
interaktif Bash kabuğu 'i' içeriklerinden, uzaklaştırılmasına neden olmaktadır $-
.
Soru şu: Bu aslında kabuğun artık etkileşimli olmadığı anlamına mı geliyor?
Bash'in kesin Tanım olarak, bu , olmamalı hiçbir yerde tanımında beri olduğu o gerekli o 'i' olmak hediyesi $-
:
An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option.
Kesin tanımın sıkı bir şekilde okunması da şu soruyu gündeme getirir: Etkileşimli bir terminalin stdin veya stderr'ı artık terminallere bağlı olmayacak şekilde yönlendirilirse, kabuk etkileşimli olmaz mı?
(Bunun cevabının "hayır" olduğu ve man sayfasının değiştirici ekleyebileceği anlaşılıyor : "standart girişi ve hatası hem terminallere bağlı ... hem de çağrılma anında " ama bilmiyorum kesin.)
Eğer cevap, "Hayır, bir kabuk etkileşimli olmayan olamaz, ne de tersi," o zaman ne kesin kabuk etkileşimli olup olmadığını belirlemek için bir yol?
Başka bir deyişle , sonradan devam eden bir "etkileşimli kabuğun" davranışları varsa , bu davranışların uygulanmaya devam etmesi gerektiğini belirlemek için ne kullanılır ?set +i
Diye kimse şüphe onu: Orada olan bir kabuk davranışları sonra kalıcı olan etkileşimli çağrılan set +i
ve bir kabuğun davranışları olmayan etkileşimli sonra devam hangi çağrılan set -i
. Örnek olarak, aşağıdaki alıntıyı göz önünde bulundurun man bash
:
COMMENTS In a non-interactive shell, or an interactive shell in which the inter- active_comments option to the shopt builtin is enabled (see SHELL BUILTIN COMMANDS below), a word beginning with # causes that word and all remaining characters on that line to be ignored. An interactive shell without the interactive_comments option enabled does not allow comments. The interactive_comments option is on by default in interac- tive shells.
Böylece interactive_comments
seçeneği ayarlayarak etkileşimli ve etkileşimli olmayan mermiler arasındaki farkı görebiliriz. Bu farkın kalıcılığı aşağıdaki komut dosyası tarafından gösterilmiştir:
#!/bin/bash
# When the testfile is run interactively,
# all three comments will produce an error
# (even the third where 'i' is not in '$-').
# When run noninteractively, NO comment will
# produce an error, though the second comment
# is run while 'i' IS in '$-'.
cat >testfile <<'EOF'
shopt interactive_comments
shopt -u interactive_comments
shopt interactive_comments
echo $-
#first test comment
set -i
echo $-
#second test comment
set +i
echo $-
#third test comment
EOF
echo 'running bash -i <testfile'
bash -i <testfile
echo 'running bash <testfile'
bash <testfile
Bu, "etkileşimli" ve " i
değerinin $-
" değerinde eşdeğer olmadığını doğrular .
${parameter:?word}
Unset parametresiyle kullanılan benzer bir test benzer sonuçlar üretir ve yine $-
kabuk etkileşimi için "gerçeğin kaynağı" olmadığını doğrular.
Son olarak, bir kabuğun kesin 'interaktiflik' özelliği nerede saklanıyor?
Ve etkileşimli bir kabuk etkileşimli olmayabilir veya tersi olabilir mi? (... bu özelliği değiştirerek mi?)