シェルで$$はどういう意味ですか?


143

一時ファイルのシェルで一意のファイル名を取得する1つの方法は、二重ドル記号($$)を使用することでした。これは時々変化する数を生成します...しかし、それを繰り返し呼び出すと、同じ数を返します。(解決策は、時間を使用することです。)

$$実際には何であるのか、なぜそれが一意のファイル名を生成する方法として提案されるのか知りたいです。

回答:


102

$$コメントで述べたように、BashにはプロセスIDがあり、さまざまな理由で一時ファイル名として使用するのは安全ではありません。

一時ファイル名については、mktempコマンドを使用します。


35
一番上の答えを見るだけの人にとって、$ 1は、公的に書き込み可能なディレクトリ(たとえば、/ tmp)に書き込む場合、単一のファイルでも問題ありません。/ tmpにシンボリックリンクを散らかすと、スクリプトが望ましくない場所に書き込まれます。mktempの方がはるかに優れています。
Chris Jester-Young

4
ええ、$$を使用すると、厄介なセキュリティホールが発生します。しないでください。
emk '09

7
または、質問をした人は、以下のより高い評価の回答を承認済み回答として設定する必要があります...
jtimberman

6
SEOに「ドル」を追加します。
Antoine

1
$$がpidを出力するだけの場合、どうして「安全でない」のでしょうか?セキュリティホールは、tmpファイル名でのPIDの使用ではなく、設計の悪さによって作成されます... tmpに行く出力の整合性をあまり気にしない場合は、そもそもそこに置くべきではないでしょうか?$$はセキュリティホールを引き起こさず、先見の明はありません
niken

113

$$bashのプロセスID(PID)です。$$通常、競合状態が発生し、攻撃者がシェルスクリプトを破壊できるため、使用はお勧めできません。たとえば、安全でない一時ファイルを作成し、セキュリティ勧告を発行しなければならなかったこれらすべての人々を見てください。

代わりに、を使用してくださいmktempmktempLinuxマニュアルページは優れています。これからのサンプルコードは次のとおりです。

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

3
ありがとう。このmktempオプション-tは廃止されました(charに問題があるためと思います-)。これらの日を使用してくださいmktemp ${tempfoo}.XXXXXX。私は自由にあなたの投稿を更新します。
セバスチャン

1
また、バックティックは廃止されたので、TMPFILE=$(mktemp)代わりに使用してください。
Michael Kopp、2016年


7

UNIXのようなオペレーティングシステムのすべてのプロセスには、(一時的に)一意の識別子であるPIDがあります。同時に実行されている2つのプロセスが同じPIDを持つことはできません。$$は、スクリプトを実行しているbashインスタンスのPIDを参照します。

これは非常に多くありませんそれは(実際に、PIDは常に再利用されます)再利用されることはありませんという意味でユニークidenifier。それがあなたに与えるのは、他の人があなたのスクリプトを実行した場合、あなたのスクリプトがまだ実行されている間に彼らが別の識別子を取得するような数です。いったん死ぬと、PIDがリサイクルされ、他の誰かがスクリプトを実行して同じPIDを取得し、同じファイル名を取得する可能性があります。

そのため、「$$がファイル名を与えるので、インスタンスがまだ実行されているときに誰かが同じスクリプトを実行すると、別の名前が付けられます」と言うのは本当に正気です。


5

$$はPIDです。あなたが注意して他の誰もそれをまったく同じ方法で行わない限り、それは実際にユニークなファイル名を生成しません。

通常、/ tmp / myprogramname $$のようなものを作成します

これを破る方法はたくさんあります。他の人が書き込める場所に書き込んでいる場合、多くのOSでは、どのPIDを持っているかを予測してねじ込むのはそれほど難しいことではありません。 rootとして、/ etc / passwdを指すシンボリックリンクとして/ tmp / yourprogname13395を作成します-そして、あなたはそれに書き込みます。

これは、シェルスクリプトで行うには悪いことです。何かのために一時ファイルを使用する場合、少なくともファイルを開く(作成する)ための「排他的」フラグを追加できる、より優れた言語を使用する必要があります。そうすれば、他のものを壊していないことを確認できます。


3

$$は、現在のシェルプロセスのPIDです。一意のファイル名を生成するのは良い方法ではありません。


3

$$は、スクリプトを実行しているシェルインタープリターのpid(プロセスID)です。現時点ではシステム上で実行されているプロセスごとに異なりますが、時間の経過とともにpidが循環し、終了すると、同じpidを持つ別のプロセスが最終的に存在します。実行している限り、pidはあなたに固有です。

上記の定義から、スクリプトで$$を何度使用しても同じ数が返されることは明らかです。

たとえば、/ tmp / myscript.scratch。$$を、非常に信頼性や安全性を必要としないものの一時ファイルとして使用できます。たとえば、trapコマンドを使用して、スクリプトの最後でそのような一時ファイルを削除することをお勧めします。

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

2

これは、bashプロセスのプロセスIDです。並行プロセスが同じPIDを持つことはありません。


2

$$は、スクリプトが実行されているシェルのプロセスIDです。詳細については、shまたはbashのマニュアルページを参照してください。manページは、コマンドライン「man sh」を使用するか、「shell manpage」をWebで検索することで見つけることができます。


2

2つ目のemkの答えを挙げましょう。$$自体を「ユニークな」ものとして使用しないでください。ファイルの場合は、mktempを使用します。同じbashスクリプト内の他のIDについては、一意性がかなり高くなる可能性があるため、「$$$(date +%s%N)」を使用します。

 -k

0

また、このコマンドでログインユーザー名を取得できます。例えば。

echo $(</proc/$$/login id). After that, you need to use getent command.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.