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?)