GNU/Linux >> Znalost Linux >  >> Linux

shebang nebo ne shebang

Místo myprg magicky detekovat, zda se používá v shebang, proč to neudělat explicitně pomocí příznaku příkazového řádku (například -f ) předat soubor jako skript?

Z vašeho příkladu v komentářích:

V teoretickém příkladu výpočtu výše. calc PI + 1 by měl vrátit 4.14159... Nyní přidání podpory pro shebang (tj. název souboru jako první parametr) by vrátilo výpočet obsažený v souboru.

Vytvořte calc proveďte soubor skriptu přes -f a poté vytvořte skripty pomocí:

#!/usr/local/bin/calc -f
$1 + 1

Řekněme, že tento soubor nazýváte addone.calc a učinit jej spustitelným. Poté jej můžete zavolat pomocí:

$ ./addone.calc PI
4.141592...

Toto volání se přeloží do vyvolání /usr/local/bin/calc -f ./addone.calc PI , takže je celkem jasné, který argument je soubor skriptu a který parametr skriptu.

Je to podobné jako awk a sed se chová.

Podobný (ale opačný) přístup je mít calc vezměte ve výchozím nastavení argument souboru skriptu (což zjednodušuje jeho použití s ​​shebang), ale přidejte příznak příkazového řádku, abyste jej mohli použít s výrazem z argumentu. Je to podobné jako sh -c '...' funguje.


Skutečným problémem je způsob, jakým jste navrhli syntaxi příkazového řádku <mypgm> . Namísto toho, abyste se snažili podporovat dva způsoby interpretace jeho argumentů, poskytněte místo toho dva způsoby jeho volání.

Příkazy Shebang jsou určeny jako skriptovací stroje, které spouštějí obsah vašeho skriptu; může to být bash , perl , nebo cokoliv jiného, ​​ale očekává se, že bude volána s názvem souboru skriptu, který se má spustit. Jak funguje bash Udělej to? To nehádá. Pokud narazí na nějaký argument, který nevypadá jako volba (nebo argument volby), považuje jej za skript, který se má provést; argumenty poté jsou předány skriptu. Například:

/bin/bash -x -e somename foo bar

Zde bude bash hledat soubor somename a zkuste jej spustit jako skript s argumenty foo a bar . Měli byste udělat totéž, protože můžete chcete napsat <mypgm> <myscript> jednoho dne na příkazovém řádku.

Pokud chcete použít <mypgm> bez použití skriptů Chcete-li být výchozí, můžete vyžadovat, aby byl skript předán s <mypgm> -f <myscript> . Takto je sed to dělá. Pak byste jej použili v řádce Shebang, jako je tento:

#!<mypgm> -f

Pokud chcete, aby velikost písmen skriptu byla výchozí, jako u bash a perl , vytvořte možnost, která říká „tentokrát není žádný skript“. Můžete použít -- za to, že <mypgm> -- one two three se nepokouší spustit one (nebo cokoli jiného) jako scénář. V takovém případě by řádek shebang zněl:

#!<mypgm>

Teď potřebuji vědět, kdy se blabla nazývá pomocí shebang nebo ne:

V C můžete tyto informace získat pomocí getauxval(AT_EXECFN) , který vám řekne název původního spustitelného souboru (tj. první argument předaný do execve(2) ) [1].

Tento řetězec je však umístěn do paměti bezprostředně za argumenty příkazového řádku a řetězce prostředí, na konec [stack] paměťovou oblast, takže ji lze načíst přímo odtud.

Například následující skript perl (pojmenujte jej foo.pl ), pokud je proveden jako spustitelný s chmod 755 foo.pl , vytiskne ./foo.pl při přímém spuštění a /usr/bin/perl při spuštění jako perl ./foo.pl :

#! /usr/bin/perl

open my $maps, "/proc/self/maps" or die "open /proc/self/maps: $!";
my $se;
while(<$maps>){ $se = hex($1), last if /^\w+-(\w+).*\[stack\]$/ }
open my $mem, "/proc/self/mem" or die "open /proc/self/mem: $!";
sysseek $mem, $se - 512, 0;
sysread $mem, $d, 512 or die "sysread: $!";
print $d =~ /([^\0]+)\0+$/, "\n";

Na novějších (>=3.5) linuxových jádrech je konec prostředí dostupný také v /proc/PID/stat (v 51. poli, jak je uvedeno v proc(5) manuálová stránka).

#! /usr/bin/perl

open my $sh, "/proc/self/stat" or die "open /proc/self/stat: $!";
my @s = <$sh> =~ /\(.*\)|\S+/g;
open my $mem, "/proc/self/mem" or die "open /proc/self/mem: $!";
seek $mem, $s[50], 0;
$/ = "\0";
my $pn = <$mem> or die "readline: $!"; chomp $pn; print "$pn\n";

[1] Linuxová jádra novější než 2.6.26 zavedla položku aux vector, která na ni ukazovala (viz potvrzení), ale název spustitelného souboru byl k dispozici na konci zásobníku dlouho předtím (od linuxu-2.0 z roku 1996).


Linux
  1. dos2unix:příkaz nenalezen

  2. chmod:příkaz nenalezen

  3. mkfs:příkaz nenalezen

  1. soubor:příkaz nenalezen

  2. tune2fs:příkaz nenalezen

  3. fsck:příkaz nenalezen

  1. ocas:příkaz nenalezen

  2. nohup:příkaz nenalezen

  3. atomic create soubor, pokud neexistuje z bash skriptu