¿Qué significa $$ en el caparazón?


143

Una vez leí que una forma 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 llama repetidamente, devuelve el mismo número. (La solución es usar el tiempo).

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

Respuestas:


102

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

Para nombres de archivos temporales, use el mktempcomando.


35
Para las personas que solo miran la respuesta principal, $$ no está bien ni siquiera para un solo archivo si se escribe en un directorio de escritura pública (por ejemplo, / tmp). Es fácil llenar / tmp con enlaces simbólicos que harán que su script escriba en algún lugar indeseable. mktemp es mucho mejor.
Chris Jester-Young

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

77
O la persona que hizo la pregunta debería establecer la respuesta mejor calificada a continuación como la respuesta aceptada ... ''
Jtimberman

66
Agrego "dólar dólar" para SEO.
Antoine

1
Si $$ solo genera el pid, ¿cómo puede ser "no seguro"? El agujero de seguridad se crea en virtud de un diseño deficiente, no se usa PID en el nombre de archivo tmp ... Si le preocupa la integridad de la salida que se envía tanto a tmp, ¿tal vez ni siquiera debería ponerla allí en primer lugar? $$ no causará agujeros de seguridad, la falta de previsión lo hará
niken

113

$$es el ID de proceso (PID) en bash. Usar $$es una mala idea, porque generalmente creará una condición de carrera y permitirá que un atacante subvierta su script de shell. Vea, por ejemplo, todas estas personas que crearon archivos temporales inseguros y tuvieron que emitir avisos de seguridad.

En cambio, use mktemp. La página de manual de Linux para mktemp es excelente. Aquí hay un código de ejemplo:

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

3
Gracias. La mktempopción -tahora está en desuso (creo que debido a problemas con el carácter -). Usa mktemp ${tempfoo}.XXXXXXestos días . Me tomo la libertad de actualizar tu publicación.
Sebastian

1
Tenga en cuenta también que la marca de retroceso está en desuso , por lo que debe usarla TMPFILE=$(mktemp).
Michael Kopp


7

Cada proceso en un sistema operativo tipo UNIX tiene un identificador único (temporalmente), el PID. No hay dos procesos que se ejecuten 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 es un identificador único en el sentido de que nunca se reutilizará (de hecho, los PID se reutilizan constantemente). Lo que sí te da es un número tal que, si otra persona ejecuta tu script, obtendrá un identificador diferente mientras el tuyo aún se está ejecutando. Una vez que el suyo muere, el PID puede reciclarse y otra persona puede ejecutar su script, 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 script mientras mi instancia todavía se está ejecutando, obtendrá un nombre diferente".


5

$$ es tu PID. Realmente 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, crearía algo como / tmp / myprogramname $$

Hay muchas maneras de romper esto, y si está escribiendo en ubicaciones a las que otras personas pueden escribir, no es demasiado difícil en muchos sistemas operativos predecir qué PID tendrá y perder el tiempo: imagine que está ejecutando como root y creo / tmp / yourprogname13395 como un enlace simbólico que apunta a / etc / passwd, y usted escribe en él.

Esto es algo malo en un script de shell. Si va a usar un archivo temporal para algo, debería estar usando un lenguaje mejor que al menos le permita agregar la bandera "exclusiva" para abrir (crear) el archivo. Entonces puedes estar seguro de que no estás golpeando otra cosa.


3

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


3

$$ es el pid (id de proceso) del intérprete de shell que ejecuta su script. Es diferente para cada proceso que se ejecuta en un sistema en este momento, pero con el tiempo el pid se envuelve, y después de que salga, eventualmente habrá otro proceso con el mismo pid. Mientras esté en ejecución, el pid es exclusivo para usted.

De la definición anterior debería ser obvio que no importa cuántas veces use $$ en un script, devolverá el mismo número.

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

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

2

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


2

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


2

Déjame la segunda respuesta de emk: no uses $$ por sí mismo como algo "único". Para archivos, use mktemp. Para otras ID dentro de la misma secuencia de comandos bash, use "$$$ (fecha +% s% N)" para una posibilidad razonablemente única de unicidad.

 -k

0

Además, puede obtener el 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.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.