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

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

130 голосов
/ 17 сентября 2008

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

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

Ответы [ 11 ]

107 голосов
/ 17 сентября 2008

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

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

tempfoo=`basename $0`
TMPFILE=`mktemp -t ${tempfoo}` || exit 1
echo "program output" >> $TMPFILE
88 голосов
/ 17 сентября 2008

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

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

17 голосов
/ 17 сентября 2008

$$ - идентификатор текущего процесса.

6 голосов
/ 17 сентября 2008

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

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

Таким образом, очень разумно сказать, что «$$ дает имя файла, такое, что если кто-то еще выполнит тот же скрипт, в то время как мой экземпляр все еще работает, он получит другое имя».

4 голосов
/ 17 сентября 2008

$$ - ваш PID. На самом деле он не генерирует уникальное имя файла, если вы не будете осторожны, и никто другой не сделает это точно так же.

Обычно вы создаете что-то вроде / tmp / myprogramname $$

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

Это плохо для сценария оболочки. Если вы собираетесь использовать временный файл для чего-то, вы должны использовать лучший язык, который, по крайней мере, позволит вам добавить «эксклюзивный» флаг для открытия (создания) файла. Тогда вы можете быть уверены, что не забиваете что-то еще.

2 голосов
/ 17 сентября 2008

Позвольте мне повторить ответ emk - не используйте $$ как нечто «уникальное». Для файлов используйте mktemp. Для других идентификаторов в том же скрипте bash используйте «$$$ (date +% s% N)» для разумного хорошего шанса уникальности.

 -k
2 голосов
/ 17 сентября 2008

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

2 голосов
/ 17 сентября 2008

$$ - это идентификатор текущего процесса оболочки. Это не хороший способ генерировать уникальные имена файлов.

1 голос
/ 17 сентября 2008

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

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

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

trap "echo 'Cleanup in progress'; rm -r $TMP_DIR" EXIT
1 голос
/ 17 сентября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...