Що означає $$ в оболонці?


143

Я одного разу прочитав, що одним із способів отримати унікальне ім’я файлу в оболонці для тимчасових файлів було використання подвійного знаку долара ( $$). Це дійсно створює число, яке час від часу змінюється ... але якщо ви дзвоните йому неодноразово, воно повертає те саме число. (Рішення - просто використовувати час.)

Мені цікаво знати, що $$насправді є, і чому це було б запропоновано як спосіб створення унікальних імен файлів.

Відповіді:


102

У Bash $$є ідентифікатор процесу, як зазначається в коментарях, це не безпечно використовувати як ім'я файлу temp з різних причин.

Для тимчасових імен файлів використовуйте mktempкоманду.


35
Для людей, які просто дивляться на головну відповідь, $$ не підходить навіть для одного файлу, якщо він записує в загальнодоступний каталог (наприклад, / tmp). Легко засмічувати / tmp символьними посиланнями, які змусять ваш сценарій писати десь небажано. mktemp набагато краще.
Кріс Єстер-Янг

4
Так, використання $$ призведе до неприємних проблем у безпеці. Не робіть цього.
emk

7
Або особа, яка поставила запитання, повинна встановити відповідь вище, ніж оцінку, як прийняту відповідь ...
jtimberman

6
Додаю "долар долара" для SEO.
Антуан

1
Якщо $$ просто виводить pid, як він може бути "не безпечним"? Дірка в безпеці створюється внаслідок поганого дизайну, а не використання PID у назві файлу tmp ... Якщо ви турбуєтесь про цілісність виводу, який так сильно переходить до tmp, можливо, ви навіть не повинні ставити його там на перше місце? $$ не спричинить загрозу в безпеці, відсутність передбачуваності
niken

113

$$- ідентифікатор процесу (PID) в bash. Використання $$- це погана ідея, оскільки вона, як правило, створює перегоновий стан, і дозволяє зловмиснику підривати ваш оболонку-скрипт. Дивіться, наприклад, усіх цих людей, які створювали незахищені тимчасові файли та повинні були видавати рекомендації щодо безпеки.

Натомість використовуйте mktemp. Сторінка man для Linux для mktemp відмінна. Ось приклад коду з нього:

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

3
Дякую. Зараз mktempваріант -tзастарілий (я думаю, що через проблеми із графіком -). Використовуйте в mktemp ${tempfoo}.XXXXXXці дні . Я смію поновлювати вашу публікацію.
Себастьян

1
Будь ласка, зауважте, що функція backtick застаріла , тому використовуйте TMPFILE=$(mktemp)замість цього.
Майкл Копп


7

Кожен процес у подібній операційній системі UNIX має (тимчасово) унікальний ідентифікатор - PID. Немає двох процесів, що працюють одночасно, не може мати однаковий PID, і $$ посилається на PID екземпляра bash, що виконує сценарій.

Це дуже не є унікальним ідентифікатором в тому сенсі, що він ніколи не буде повторно використаний (дійсно, PID використовуються постійно). Це дає вам такий номер, що, якщо інша людина запустить ваш сценарій, він отримає інший ідентифікатор, поки ваш все ще працює. Як тільки ваш помер, PID може бути перероблений, і хтось інший може запустити ваш сценарій, отримати той самий PID і так отримати те саме ім’я файлу.

Таким чином, можна сказати, що "$$ дає ім'я файлу лише таким розумним, що якщо хтось інший запускає той самий сценарій, у якому все ще працює мій екземпляр, він отримає інше ім'я".


5

$$ - ваш PID. Він насправді не генерує унікальне ім’я файлу, якщо ви не обережні, і ніхто більше не робить це точно так само.

Зазвичай ви створюєте щось на кшталт / tmp / myprogramname $$

Існує так багато способів вирішити це, і якщо ви пишете в місця, які інші люди можуть написати, що на багатьох ОС не так вже й складно передбачити, який саме PID матимете, і накрутити - уявіть, що ви працюєте як root, і я створюю / tmp / yourprogname13395 як символьне посилання, що вказує на / etc / passwd - і ви пишете в нього.

Це погано, що потрібно робити в сценарії оболонки. Якщо ви збираєтесь використовувати тимчасовий файл для чогось, ви повинні використовувати кращу мову, яка принаймні дозволить вам додати "ексклюзивний" прапор для відкриття (створення) файлу. Тоді ви можете бути впевнені, що не клопотите щось інше.


3

$$ - pid поточного процесу оболонки. Це не гарний спосіб генерування унікальних імен файлів.


3

$$ - pid (ідентифікатор процесу) інтерпретатора оболонки, який працює з вашим сценарієм. Наразі кожен процес, що працює в системі, відрізняється, але з часом підкатка загортається, і після виходу зрештою відбудеться ще один процес із тим самим Pid. Доки ви працюєте, pid унікальний для вас.

З вищенаведеного визначення повинно бути очевидним, що незалежно від того, скільки разів ви використовуєте $$ у сценарії, він поверне те саме число.

Ви можете використовувати, наприклад, /tmp/myscript.scratch.$$ як свій тимчасовий файл для речей, які не повинні бути надзвичайно надійними або безпечними. Добре практично видаляти такі тимчасові файли в кінці сценарію, використовуючи, наприклад, команду trap:

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

2

Це ідентифікатор процесу bash-процесу. Жоден паралельний процес ніколи не буде мати однаковий PID.


2

$$ - ідентифікатор процесу оболонки, в якій працює ваш скрипт. Докладніші відомості див. На сторінці man для sh або bash. Сторінки man можна знайти або за допомогою командного рядка "man sh", або за допомогою пошуку в Інтернеті для "man manpage"


2

Дозвольте мені відповісти другий емк - не використовуйте $$ сам як "унікальне". Для файлів використовуйте mktemp. Для інших ідентифікаторів у межах того самого сценарію bash використовуйте "$$$ (дата +% s% N)" для досить хорошого шансу на унікальність.

 -k

0

Також ви можете захопити ім'я користувача для входу за допомогою цієї команди. Напр.

echo $(</proc/$$/login id). After that, you need to use getent command.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.