28 Mayıs 2020 Perşembe

Shebang

Giriş
Açıklaması şöyle. Shebang satırı, betiğimizi yani script'imizi hangi uygulamanın çalıştıracağını belirtir.
Shebang commands are meant to be script engines that execute the content of your script; it might be bash, perl, or whatever, but the expectation is that it is called with the file name of a script to execute.
Bash İçin Shebang
set komutu ile kullanılan seçenekler aynı zamanda Shebang olarak ta kullanılabilir. Açıklaması şöyle
All of the single-character shell options documented in the description of the set builtin command, including -o, can be used as options when the shell is invoked. [...]

Örnek
Şöyle yaparız
#!/bin/bash -e
Bash Dışında Başka Uygulama Çalıştırmak
Örnek - python
Python için şöyle yaparız
#!/usr/bin/env python
Örnek - python3
Şöyle yaparız.
#!/usr/bin/python3
print('Hello world!')
Örnek - calc
Elimizde şöyle bir kod olsun. Bunu addone.calc olarak kaydedelim.
#!/usr/local/bin/calc -f
$1 + 1
Şöyle yaparız.
$ ./addone.calc PI
4.141592...
Aslında şuna çevrilir.
/usr/local/bin/calc -f ./addone.calc PI
Örnek - sh
Şöyle yaparız.
#!/bin/sh
veya şöyle yaparız.
#!/usr/bin/env sh
Açıklaması şöyle.
Setting to #!/bin/sh will go directly to that file /bin/sh.

Setting to #!/usr/bin/env sh will execute /usr/bin/env with an argument of sh. This will cause the script to be executed by sh in your PATH variable rather than explicitly with /bin/sh.
Shebang Kullanmak Zorunda Mıyız ?
Değiliz :) Shebang'e sahip olmayan shell script'leri halen çalıştırılabiliyor. Ancak örneğin dosya perl dosyası ise işe yaramaz.

Shebang Yoksa Bu Nasıl Oluyor?
Açıklaması şöyle. Yani eğer shebang yoksa kabuk yine de dosyayı okuyup çalıştırabilir. Ancak dosyanın shell dosyası olması lazım.
There are different ways to "execute" a script, that have subtle differences:

- run sh /path/to/script: The script needs no execute permissions! In fact you execute sh, which in turn reads and interprets the script. So the moment you may read it, you can not execute it, but tell the shell to read it and act upon it which is nearly the same thing as executing it.

- directly run /path/to/script after adding a #!/bin/sh header and giving execution privileges. In this case you execute the script itself, with the shebang header telling which shell to load

- run . /path/to/script: This tells your current shell to load the script and interpret it as if you were inputing its content into the shell prompt. Again no execution privileges are needed, as you don't execute the file, but read it.

You can make the differences visible with a script, that says just echo "$0". In the first case it will output the path to sh, in the second case the path to the script and in the third case the path to your current shell.
Benzer bir açıklama şöyle.
The parent shell, where you entered ./myscript.sh, first tried to execve it, which is where the shebang line would take effect if present. When this works, the parent is unaware of the difference between scripts and ELFs because the kernel takes care of it.

The execve failed, so an ancient unix compatibility feature, predating the existence of shebang lines, was activated. It guessed that a file which has execute permission but is not recognized as a valid executable file by the kernel must be a shell script.

Usually the parent shell guesses that the script is written for the the same shell (minimal Bourne-like shells run the script with /bin/sh, bash runs it as a bash subprocess), csh does some more complicated guessing based on the first character because it predates shebang too and it needed to coexist with Bourne shell).

You need a shebang line when you know these guesses will be wrong (for example with the shebang is #!/usr/bin/perl), or when you don't trust the guessing to work consistently, or when the script needs to be runnable by a parent process that is not a shell itself.

Hiç yorum yok:

Yorum Gönder