4 Ekim 2020 Pazar

bash kodlama - Subshell

Giriş
Bash ile subshell kullanmanın 3 yöntemi var.
1. (...) şeklinde kullanmak
2. <(...) şeklinde process substitution şeklinde kullanmak
3. "$(...)" şeklinde command substitution şeklinde kullanmak

2 ve 3 numaralar da subshell içinde çalışır. Açıklaması şöyle
A command substitution $(...) will be replaced by the output of the command, while a process substitution <(...) will be replaced by a filename from which the output of the command may be read. The command, in both instances, will be run in a subshell.
(...) ve {...} Farklı Şeylerdir - Subshell vs Curly Braces
Açıklaması şöyle
(list)

list is executed in a subshell environment (see COMMAND EXECUTION ENVIRONMENT below). Variable assignments and builtin commands that affect the shell's environment do not remain in effect after the command completes. The return status is the exit status of list.
Diğer açıklama şöyle
{ list; }

list is simply executed in the current shell environment. list must be terminated with a newline or semicolon. This is known as a group command. The return status is the exit status of list. Note that unlike the metacharacters ( and ), { and } are reserved words and must occur where a reserved word is permitted to be recognized. Since they do not cause a word break, they must be separated from list by whitespace or another shell metacharacter.
Örnek
Elimizde şöyle bir kod olsun. Burada or opertor'den sonra gelen kod subshell içinde çalışır ve exit status var olduğu için gösterilebilir.
no_func || (
    echo "there is nothing"
    exit 1
)

echo $?
Çıktı olarak şunu alırız
$ ./script1.sh
./script1.sh: line 3: no_func: command not found
there is nothing 
1 # <-- exit status of subshell
$ echo $?
0 # <-- exit status of script
Kodu değiştirelim ve subshell yerine curly brace kullansın. Şöyle olsun
no_func || {
    echo "there is nothing"
    exit 1
}

echo $?
Çıktı olarak şunu alırız. Bu sefer subshell yoktur ve exit 1 ile tüm betik sonlanır. Bu yüzden "echo $?" komutu da çalışmaz.
/Users/myname/bin/ex5: line 34: no_func: command not found
there is nothing
Subshell Parent Shell'in Ortam Değişkenlerini Görebilir
Açıklaması şöyle
The parentheses () open a new subshell that will inherit the environment of its parent. However, the subshell will exit as soon as the commands running it it are done, returning you to the parent shell and the cd will only affect the subshell, therefore your PWD will remain unchanged.

However, note that the subshell will also copy all shell variables, so you cannot pass information back from the subshell function to the main script via global variables.
Örnek
Eğer bir metod içinde yapmak istersek şöyle yaparız
doStuffAt() (
  cd -- "$1" || exit # the subshell if cd failed.
  # do stuff
)

Hiç yorum yok:

Yorum Gönder