O problema com todos os seus comandos é que você está usando a citação errada. Cada comando no crontab é um trecho de código shell, que é processado por um shell. O shell de processamento do comando crontab é definido pela configuração da variável SHELL
no arquivo crontab, cujo padrão é /bin/sh
.
Quando /bin/sh
(ou qualquer shell compatível) executa o script /bin/bash -c "readlink /proc/$$/exe >> /root/printenv"
, uma das etapas após a análise da linha de comando é executar qualquer variável ou substituição de comando. Há uma substituição de variável aqui: o $$
que está dentro de uma cadeia de aspas duplas. Portanto, $$
é substituído pelo ID do processo /bin/sh
. Digamos que esse ID de processo seja 1234. O shell chamado pelo cron executa o comando /bin/bash
com os argumentos -c
e readlink /proc/1234/exe >> /root/printenv
. A saída indica que /bin/sh
é um link simbólico para /bin/bash
.
Se você usar aspas simples em vez de aspas duplas, o shell invocado pelo cron não executará nenhuma substituição de variável e executará o comando /bin/bash
com os argumentos -c
e readlink /proc/$$/exe >> /root/printenv
. Bash então analisa esse comando, realiza a substituição de $$
por seu próprio ID de processo e executa readlink
com o argumento 1234
.
Observe que, dependendo do shell, a saída desse comando pode não ser o binário do shell, pode ser /bin/readlink
. A razão é que existe uma otimização no bash (e vários outros shells): quando a última coisa que o shell precisa fazer é executar um comando externo, ele não executa esse comando em um processo filho, ele substitui o processo do shell imagem. (Executar um programa no Unix sempre funciona substituindo a imagem do processo por outros ; programas geralmente se dupliquem antes de fazer isso, mas não é uma obrigação.) Uma vez que o bash detecta que executar readlink
é a última coisa que tem que fazer, ele executa readlink
no mesmo processo 1234, então readlink /proc/1234/exe
reports %código%. O Bash executa essa otimização se você acabou de executar um comando
bash -c 'readlink /proc/$$/exe'
mas não se houver um redirecionamento. Algumas conchas (por exemplo, traço) não realizam essa otimização. Algumas conchas, como ksh, são um pouco mais espertas e otimizam /bin/readlink
, mas não otimizam, e. %código%. (Exercício: por que é impossível otimizar esse?)