Что означает $$ в оболочке?


143

Однажды я прочитал, что одним из способов получения уникального имени файла в оболочке для временных файлов было использование двойного знака доллара ( $$). Это производит число, которое время от времени меняется ... но если вы звоните ему несколько раз, он возвращает тот же номер. (Решение состоит в том, чтобы просто использовать время.)

Мне любопытно узнать, что на $$самом деле и почему это будет предложено в качестве способа генерирования уникальных имен файлов.

Ответы:


102

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

Для временных имен файлов используйте mktempкоманду.


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

4
Да, использование $$ вызовет неприятную дыру в безопасности. Не делай этого.
Емк

7
Или человек, который задал вопрос, должен установить более высокий
оценочный

6
Я добавляю «доллар доллар» для SEO.
Антуан

1
Если $$ просто выводит pid, как это может быть «небезопасно»? Брешь в безопасности создается из-за плохого дизайна, а не использования PID в имени файла tmp ... Если вы заботитесь о целостности вывода, который так много идет в tmp, может быть, вам даже не стоит помещать его туда в первую очередь? $$ не создаст дыру в безопасности, отсутствие предвидения
niken

113

$$это идентификатор процесса (PID) в bash. Использование $$- плохая идея, потому что обычно это создает условия гонки и позволяет злоумышленнику подорвать ваш сценарий оболочки. Посмотрите, например, всех этих людей, которые создали небезопасные временные файлы и должны были выпускать рекомендации по безопасности.

Вместо этого используйте mktemp. Страница людей Linux для Mktemp отлично. Вот пример кода из этого:

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

3
Спасибо. mktempВариант -tтеперь осуждается (я думаю , что из - за проблем с угл -). Используйте mktemp ${tempfoo}.XXXXXXэти дни . Я позволю себе обновить ваш пост.
Себастьян

1
Также обратите внимание, что обратная пометка устарела , поэтому используйте 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. Пока вы работаете, pid уникален для вас.

Из приведенного выше определения должно быть очевидно, что независимо от того, сколько раз вы используете $$ в скрипте, он будет возвращать одно и то же число.

Вы можете использовать, например, /tmp/myscript.scratch.$$ в качестве временного файла для вещей, которые не обязательно должны быть чрезвычайно надежными или безопасными. Рекомендуется удалять такие временные файлы в конце вашего скрипта, используя, например, команду trap:

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

2

Это идентификатор процесса bash. Никакие параллельные процессы никогда не будут иметь одинаковый PID.


2

$$ - это идентификатор процесса оболочки, в которой работает ваш скрипт. Для получения дополнительной информации см. Справочную страницу для sh или bash. Страницы руководства могут быть найдены либо с помощью командной строки "man sh", либо с помощью поиска в Интернете "man-страницы оболочки"


2

Позвольте мне повторить ответ emk - не используйте $$ как нечто «уникальное». Для файлов используйте mktemp. Для других идентификаторов в том же скрипте bash используйте «$$$ (date +% 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.