A seguir, o que acabei usando para criar de maneira confiável um diretório temporário que funcione no Linux e no Darwin (todas as versões anteriores ao Mac OS X 10.11), sem codificação $TMPDIR
ou /tmp
:
mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`
Fundo:
O comando GNU mktemp não requer argumentos. O Plain mktemp
funcionará e cria um arquivo temporário no diretório temporário do sistema.
O Plain mktemp -d
criará um diretório em vez de um arquivo, que é o que você deseja 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 modelo tmp.XXXXXXXXXX
para o nome do subdiretório (ou arquivo). Para personalizar este modelo, a -t
opção pode ser usada.
O mktemp do OSX não possui modelo padrão e requer que um modelo seja especificado. Infelizmente, onde o GNU mktemp usa o modelo como -t
opção, no OSX isso é passado como argumento posicional. Em vez disso, o mktemp do OSX tem uma -t
opção que significa outra coisa. A -t
opção no OSX está documentada como um "prefixo" para o modelo. Ele é expandido para {prefix}.XXXXXXXX
, portanto, adiciona os Xs automaticamente (por exemplo, mktemp -d -t example
pode ser criado example.zEJZWCTQ
no diretório temp).
Fiquei surpreso ao descobrir que, em muitos ambientes Linux, não$TMPDIR
está definido por padrão. Muitos programas CLI suportam quando definidos, mas ainda precisam de um padrão . Isso significa que a passagem para mktemp ou mkdir é perigosa, pois pode produzir no diretório raiz do disco local (devido ao fato de $ TMPDIR estar desconfigurado e se tornar uma cadeia vazia)./tmp
$TMPDIR/example.XXXXXXXX
/example.XXXXXXXX
No OSX, $TMPDIR
sempre está definido e (pelo menos no shell padrão) não está definido como /tmp
(que é um link simbólico para /private/tmp
), mas como /var/folders/dx/*****_*************/T
. Portanto, o que fazemos para o OSX, deve respeitar esse comportamento padrão.
Concluindo, a seguir, o que acabei usando para criar de maneira confiável um diretório temporário que funcione no Linux e no Darwin (Mac OS X), sem codificar permanentemente $TMPDIR
ou /tmp
:
mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`
A primeira parte é para Linux. Este comando falhará no Darwin (Mac OS X) com o código de status do erro 1
respondendo com "use: ...". É por isso que ignoramos o stderr e, em vez disso, executamos a variante do Mac. O mytmpdir
prefixo é usado apenas no Mac (onde é necessário definir essa opção).