Eu notei isso antes, mas foi trazido novamente quando eu estava respondendo " Como mover o diretório para um diretório com o mesmo nome? ":
O mktemp
utilitário no macOS não se comporta da mesma forma que o utilitário de mesmo nome no Linux ou BSD (ou pelo menos no OpenBSD) em relação à TMPDIR
variável de ambiente.
Para criar um arquivo temporário no diretório atual , geralmente posso dizer
tmdfile=$(TMPDIR=. mktemp)
ou
tmpfile=$(TMPDIR=$PWD mktemp)
(e da mesma forma para um diretório temporário com mktemp -d
).
No macOS, terei que forçar o utilitário a usar o diretório atual, fornecendo um modelo real, como em
tmpfile=(mktemp ./tmp.XXXXXXXX)
porque usar o mais conveniente tmpfile=$(TMPDIR=. mktemp)
ignoraria a TMPDIR
variável e criaria o arquivo em /var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T
ou em um diretório com nome semelhante.
O manual para mktemp
no macOS menciona que
Se a
-t prefix
opção for fornecida,mktemp
gerará uma string de modelo com base no prefixo e na_CS_DARWIN_USER_TEMP_DIR
variável de configuração, se disponível. Os locais de fallback, se_CS_DARWIN_USER_TEMP_DIR
não estiverem disponíveis, sãoTMPDIR
e/tmp
.
No meu sistema, _CS_DARWIN_USER_TEMP_DIR
parece não estar definido:
$ getconf _CS_DARWIN_USER_TEMP_DIR
getconf: no such configuration parameter `_CS_DARWIN_USER_TEMP_DIR'
mas por exemplo
tmpfile=$(TMPDIR=. mktemp -t hello)
ainda cria um arquivo em /var/folders/.../
(também ao usar $PWD
no lugar de .
).
estou percebendo isso
$ getconf DARWIN_USER_TEMP_DIR
/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T/
mas isso não me ajuda muito, pois eu não saberia como alterar esse valor.
Diz-se que o utilitário macOS mktemp
vem do FreeBSD, que por sua vez o obteve do OpenBSD (que deve ter sido há bastante tempo).
Pergunta:
Isso é um bug (ou omissão) na implementação do macOS do mktemp
? Como faço para alterar o DARWIN_USER_TEMP_DIR
valor (ou _CS_DARWIN_USER_TEMP_DIR
mencionado pelo manual) de dentro de um script (o ideal é desativá-lo para que $TMPDIR
tenha precedência)?
Este é o diretório local do usuário do Darwin . Seu nome é simplesmente uma codificação de base 32 modificada da concatenação de seu UUID de usuário do MacOS e seu ID de usuário do MacOS (BSD). As duas primeiras letras da codificação são usadas como um sistema "bucket" para tentar manter os tamanhos dos diretórios baixos. Esses dois caracteres são os primeiros 10 bits codificados do UUID do usuário, porque na base 32 um dígito é, obviamente, 5 bits.
Seus subdiretórios são os diretórios temporários locais do usuário e de cache local do usuário . Seus nomes costumavam ser
-Caches-
e,-Tmp-
mas esses foram abreviados paraC
eT
. Deve ficar claro que todos esses nomes são fixos e imutáveis, a menos que você queira alterar seu ID de usuário ou UUID de usuário.Quando um aplicativo chama
confstr(_CS_DARWIN_USER_TEMP_DIR,…)
, a biblioteca C primeiro tenta garantir que você tenha um diretório local do usuário e, em seguida, tenta garantir que você tenha um diretório temporário local do usuário dentro dele.Garantir que você tenha um diretório local do usuário não é trivial, porque você não tem acesso de gravação ao
/var/folders
. Portanto, existe um daemon dedirhelper
inicialização Mach que é executado com privilégios de superusuário e que cria esses diretórios com segurança, respondendo a chamadas Mach IPC de aplicativos de dentro da implementaçãoconfstr()
em suas bibliotecas C. Você tem acesso de gravação ao diretório local do usuário ( uma vez criado) e, portanto, as bibliotecas C apenas seus filhos diretamente, se eles ainda não existirem.mkdir()
Se isso for bem-sucedido, o
mktemp
programa nunca examinará o valor daTMPDIR
variável de ambiente, porque o fallback nomktemp
código de 's é de chamarconfstr()
para chamar egetenv()
não o contrário.confstr(_CS_DARWIN_USER_TEMP_DIR,…)
quase sempre terá sucesso. Seus modos de falha são coisas como odirhelper
daemon de inicialização que não pode ser executado ou a tentativa de criar oT
subdiretório falhando com um erro diferente de que o diretório já existe.Você pode colocar algo diferente de um diretório como
T
, mas isso será limpo regularmente pelodirhelper
daemon de inicialização, que também é o que exclui coisas em/var/folders
. A desativação dodirhelper
daemon de inicialização causará problemas próprios, entre os quais/var/folders
não será a limpeza. Negar a si mesmo a permissão de gravação no diretório local do usuário interferirá potencialmente em todos os outros usos dele, sendo usado para mais do que apenas umT
subdiretório.Sua melhor opção (além de fornecer um modelo) é fazer
T
um link simbólico, mas isso ainda está longe de ser bom porque, é claro, afetará todos os aplicativos em execução que podem, no mesmo instante, querer criar um arquivo temporário Arquivo.Nem
DARWIN_USER_TEMP_DIR
nem_CS_DARWIN_USER_TEMP_DIR
são nomes de variáveis. São nomes, para ogetconf
utilitário e para aconfstr()
função de biblioteca, de uma string de configuração.