it-swarm-eu.dev

Co znamenají $$ ve skořápce?

Jednou jsem četl, že jedním ze způsobů, jak získat jedinečný název souboru v prostředí Shell pro dočasné soubory, je použít dvojitý znak dolaru ($$). To vytváří číslo, které se čas od času mění, ale pokud jej opakovaně voláte, vrátí stejné číslo. (Řešením je použít čas.)

Jsem zvědavý, co vlastně je $$ a proč by to bylo navrhováno jako způsob, jak generovat jedinečná jména souborů.

125
Kitty

V Bash $$ je ID procesu, jak je uvedeno v komentářích, které není bezpečné použít jako soubor temp z různých důvodů.

Pro dočasné názvy souborů použijte příkaz mktemp.

85
Joe Skora

$$ je ID procesu (PID) v bash. Použití $$ je špatný nápad, protože obvykle vytvoří podmínku závodu a umožní, aby útočník útočil na skript Shell. Viz například všechny tyto osoby , kteří vytvořili nezabezpečené dočasné soubory a museli vydávat bezpečnostní doporučení.

Místo toho použijte mktemp. Manuální stránka Linux pro mktemp je vynikající. Zde je příklad kódu:

tempfoo=`basename $0`
TMPFILE=`mktemp -t ${tempfoo}` || exit 1
echo "program output" >> $TMPFILE
102
emk

$$ je id aktuálního procesu.

17
Flint

Každý proces v operačním systému UNIX má (dočasně) jedinečný identifikátor, PID. Žádné dva procesy spuštěné ve stejnou dobu nemohou mít stejný kód PID a hodnota $$ označuje kód PID instance instance bash, ve kterém je skript spuštěn.

Toto je velmi ne jedinečný identifikátor v tom smyslu, že nikdy nebude znovu použit (opravdu, PIDs jsou opakovaně používány). To, co vám dává, je takové číslo, že pokud váš skript spouští jiná osoba, bude mít jiný identifikátor, zatímco váš bude stále spuštěn. Jakmile váš zemře, PID může být recyklován a někdo jiný může spustit váš skript, získat stejný PID a získat stejný název souboru.

Jako takový, to je jen opravdu rozumné říci "$$ dává název souboru, že pokud někdo jiný spustí stejný skript whist moje instance je stále běží, budou mít jiné jméno".

6
Adam Wright

$$ je vaše PID. Není to opravdu generovat jedinečný název souboru, pokud jste opatrní a nikdo jiný to přesně stejným způsobem. 

Typicky byste vytvořili něco jako/tmp/myprogramname $$

Existuje mnoho způsobů, jak tento problém porušit, a pokud píšete na místa, jiní lidé mohou psát, že na mnoha operačních systémech není příliš těžké předvídat, co PID budete mít, a přišroubovat - představte si, že běžíte jako root a vytvořím/tmp/yourprogname13395 jako symbolický odkaz na soubor/etc/passwd - a zapíšete do něj.

To je špatná věc, kterou byste měli dělat ve skriptu Shell. Pokud budete chtít použít dočasný soubor pro něco, měli byste používat lepší jazyk, který vám alespoň umožní přidat "exkluzivní" příznak pro otevření (vytvoření) souboru. Pak si můžete být jisti, že neberete něco jiného.

4
JBB

Dovolte mi, abych odpověděl na druhou emk - nepoužívejte $$ jako „jedinečný“. Pro soubory použijte mktemp. Pro ostatní ID v rámci stejného bash skriptu použijte "$$$ (datum +% s% N)" pro rozumně dobrou šanci na jedinečnost.

 -k
2
Kevin Little

$$ je pid aktuálního procesu Shell. Není to dobrý způsob, jak generovat jedinečná jména souborů.

2
leif

$ $ Je id procesu Shell, ve kterém je váš skript spuštěn. Další podrobnosti naleznete v manuálové stránce sh nebo bash. Manové stránky lze nalézt buď pomocí příkazového řádku "man sh", nebo pomocí webu "Shell manpage".

2
Shannon Nelson

Je to procesní proces procesu bash. Žádné souběžné procesy nikdy nebudou mít stejný PID.

1
Chris

$$ je pid (id procesu) interpreta Shell, který spouští skript. Je to jiné pro každý proces běžící na systému v tuto chvíli, ale postupem času se pid zabalí a poté, co odejdete, bude další proces s tímtéž pidem nakonec.

Z výše uvedené definice by mělo být zřejmé, že bez ohledu na to, kolikrát používáte $$ ve skriptu, vrátí stejné číslo. 

Můžete použít např. /tmp/myscript.scratch.$ jako dočasný soubor pro věci, které nemusí být extrémně spolehlivé nebo bezpečné. Je dobré odstranit takové dočasné soubory na konci skriptu, například pomocí příkazu trap:

trap "echo 'Cleanup in progress'; rm -r $TMP_DIR" EXIT
1
Arkadiy

Také můžete pomocí tohoto příkazu uchopit přihlašovací jméno uživatele. Např.

echo $(</proc/$$/login id). After that, you need to use getent command.
0
Obivan