A seguir, o que acabei usando para criar de forma confiável um diretório temporário que funciona no Linux e no Darwin (todas as versões anteriores ao Mac OS X 10.11), sem codificar $TMPDIR
ou /tmp
:
mytmpdir='mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir''
Antecedentes:
O comando GNU mktemp não requer argumentos. O mktemp
simples funcionará e criará um arquivo temporário no diretório temporário do sistema.
O mktemp -d
simples criará um diretório em vez de um arquivo, que é o que você gostaria de usar no Linux.
(gnu-coreutils)$ man mktemp
> ..
> If DIR is not specified, uses $TMPDIR if set, else /tmp.
> ..
Por padrão, o GNU mktemp usa o template tmp.XXXXXXXXXX
para o nome do subdiretório (ou arquivo). Para personalizar este modelo, a opção -t
pode ser usada.
O mktemp do OSX não possui um modelo padrão e requer que um modelo seja especificado. Infelizmente, onde o GNU mktemp toma o template como -t
, no OSX isso é passado como argumento posicional. Em vez disso, o mktemp do OSX tem uma opção -t
que significa outra coisa. A opção -t
no OSX é documentada como um "prefixo" para o modelo. Ele é expandido para {prefix}.XXXXXXXX
, então adiciona automaticamente o Xs (por exemplo, mktemp -d -t example
poderia criar example.zEJZWCTQ
no diretório temporário).
Fiquei surpreso ao descobrir que, em muitos ambientes Linux, $TMPDIR
é não definido por padrão. Muitos programas CLI oferecem suporte a ele quando configurados, mas ainda precisam de um padrão para /tmp
. Isso significa passar $TMPDIR/example.XXXXXXXX
para mktemp ou o mkdir é perigoso porque pode produzir /example.XXXXXXXX
no diretório raiz do disco local (devido a $ TMPDIR ser desconfigurado e se tornar uma string vazia).
No OSX, $TMPDIR
é sempre definido e (pelo menos no shell padrão) não está definido como /tmp
(que é um link simbólico para /private/tmp
), mas para /var/folders/dx/*****_*************/T
. Então, o que quer que façamos para a OSX, devemos honrar esse comportamento padrão.
Concluindo, o que acabei de usar foi o criar de forma confiável um diretório temporário que funciona no Linux e no Darwin (Mac OS X), sem codificar $TMPDIR
ou /tmp
:
mytmpdir='mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir''
A primeira parte é para o Linux. Este comando falhará no Darwin (Mac OS X) com o código de status de erro 1
respondendo com "usage: ...". É por isso que ignoramos o stderr e, em vez disso, executamos a variante do Mac. O prefixo mytmpdir
é usado apenas no Mac (onde é necessário definir essa opção).