2008-09-16 36 views
109

Una vez leí que una manera de obtener un nombre de archivo único en un shell para archivos temporales era usar un signo de dólar doble ($$). Esto produce un número que varía de vez en cuando ... pero si lo llamas repetidamente, devuelve el mismo número. (La solución es simplemente usar el tiempo.)

Tengo curiosidad por saber qué es realmente $$, y por qué sería sugerido como una forma de generar nombres de archivo únicos.

Respuesta

69

En Bash $$ es el ID del proceso, como se señala en los comentarios, no es seguro usarlo como nombre de archivo temporal por diversas razones.

Para nombres de archivos temporales, use el comando mktemp.

+33

Para las personas que basta con ver la respuesta más común, $$ no está muy bien, incluso para un solo archivo, si la escritura a un directorio público-grabables (por ejemplo,/tmp). Es fácil tirar basura/tmp con enlaces simbólicos que harán que el script escriba en algún lugar indeseable. mktemp es mucho mejor. –

+4

Sí, usar $$ causará un desagradable agujero de seguridad. No lo hagas – emk

+2

alguien con suficiente representante debe editar la respuesta ... – dwestbrook

14

$$ es la identificación del proceso actual.

2

$$ es el pid del proceso de shell actual. No es una buena forma de generar nombres de archivo únicos.

1

Es la identificación del proceso del proceso bash. Ningún proceso simultáneo tendrá el mismo PID.

6

Todos los procesos en un sistema operativo similar a UNIX tienen un identificador único (temporalmente), el PID. No hay dos procesos ejecutándose al mismo tiempo que puedan tener el mismo PID, y $$ se refiere al PID de la instancia de bash que ejecuta el script.

Esto es mucho no un identificador único en el sentido de que nunca será reutilizado (de hecho, los PID se reutilizan constantemente). Lo que sí le proporciona es un número tal que, si otra persona ejecuta su secuencia de comandos, obtendrá un identificador diferente mientras que el suyo todavía se está ejecutando. Una vez que el tuyo fallezca, el PID se puede reciclar y otra persona podría ejecutar tu secuencia de comandos, obtener el mismo PID y obtener el mismo nombre de archivo.

Como tal, es realmente sensato decir "$$ da un nombre de archivo tal que si alguien más ejecuta el mismo guión cuando mi instancia todavía está en ejecución, obtendrá un nombre diferente".

1

$$ es la identificación del proceso del shell en el que se está ejecutando el script. Para obtener más detalles, consulte la página de manual de sh o bash. Las páginas man se pueden encontrar usando una línea de comando "man sh", o buscando en la web "shell manpage"

4

$$ es su PID. En realidad, no genera un nombre de archivo único, a menos que tenga cuidado y nadie más lo haga exactamente de la misma manera.

Por lo general, debes crear algo así como/tmp/myprogramname $$

No tenemos tantas formas de romper esto, y si usted está escribiendo a los lugares de otras personas puede escribir en él no es demasiado difícil en muchas Para predecir qué PID va a tener y atornillar: imagine que está ejecutando como root y creo/tmp/yourprogname13395 como un enlace simbólico que apunta a/etc/passwd y escribe en él.

Esto es algo malo de hacer en un script de shell. Si vas a usar un archivo temporal para algo, deberías estar usando un lenguaje mejor que al menos te permita agregar el indicador "exclusivo" para abrir (crear) el archivo. Entonces puedes estar seguro de que no estás peleando con otra cosa.

1

$$ es el pid (id del proceso) del intérprete de shell que ejecuta su secuencia de comandos. Es diferente para cada proceso que se ejecuta en un sistema en este momento, pero con el tiempo el pid se ajusta, y después de que salga habrá otro proceso con el mismo pid eventualmente.Mientras estés corriendo, el pid es único para ti.

De la definición anterior, debería ser obvio que no importa cuántas veces utilice $$ en una secuencia de comandos, devolverá el mismo número.

Puede usar, p. /tmp/myscript.scratch.$$ como su archivo temporal para cosas que no necesitan ser extremadamente confiables o seguras. Es una buena práctica para eliminar estos archivos temporales al final de la secuencia de comandos, utilizando, por ejemplo, el comando trampa:

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

$$ es el identificador de proceso (PID) en bash. Usar $$ es una mala idea, porque generalmente creará una condición de carrera y permitirá que un atacante derribe su script de shell. Ver, por ejemplo, todos these people que crearon archivos temporales inseguros y tuvieron que emitir avisos de seguridad.

En su lugar, use mktemp. El Linux man page for mktemp es excelente. Aquí hay un código de ejemplo de ello:

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

Gracias. La opción 'mktemp'' -t' ahora está en desuso (creo que debido a problemas con el char '-'). ** Use 'mktemp $ {tempfoo} .XXXXXX' estos días **. Me tomo la libertad de actualizar tu publicación. – Sebastian

+0

Tenga en cuenta que el [backtick estaba en desuso] (http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xcu_chap02.html#tag_23_02_06_03), entonces use 'TMPFILE = $ (mktemp)' en su lugar. –

1

Let Me segunda respuesta de EMK - no utilice $$ por sí mismo como algo "único". Para archivos, use mktemp. Para otros ID dentro del mismo script bash, use "$$$ (date +% s% N)" para obtener razonablemente con buenas posibilidades de ser único.

-k 
0

También, Usted puede agarrar nombre de usuario de inicio de sesión a través de este comando. P.ej.

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