unshare(1)
вообще не звонит clone(2)
. После вызова системного вызова unshare(CLONE_NEWUSER)
программа unshare
выполняется до программы, указанной в командной строке, или программы из переменной окружения $SHELL
.
В вашем случае это bash
, который разветвляется -много(fork(2)
является оболочкой для clone(2)
в настоящее время )при обработке команд из его сценариев инициализации(~/.bashrc
и т. д. ).
Нечто похожее на repr
в Python — это printf %q
, которое можно комбинировать с printf -v
, которое «выводит» в другую переменную вместо стандартного вывода. (хотя и не является стандартом -, он поддерживается в printf, встроенном -из bash и zsh):
[prompt] foo=$(cat <<'EOT'
'"'<>\`'"'''()*@@@@$$$$````'''''
EOT
)
[prompt] printf '%q\n' "$foo"
\'\"\'\<\>\\\`\'\"\'\'\'\(\)\*@@@@\$\$\$\$\`\`\`\`\'\'\'\'\'
[prompt] printf -v bar %q "$foo"
Одно из практических применений этого — когда вы хотите передавать команды через несколько ssh (, например. когда нельзя настроить переадресацию на промежуточных хостах с ssh -J
), и даже один уровень экранирования слишком много, чтобы иметь возможность отслеживать (по крайней мере для меня):
[prompt] cmd='echo "$USER'\''s \$HOME on $HOSTNAME is $HOME"'
[prompt] ssh localhost "$cmd"
luser12's $HOME on kgbvax is /home/luser12
[prompt] printf -v cmd %q "$cmd"
[prompt] ssh localhost ssh localhost "$cmd"
luser12's $HOME on kgbvax is /home/luser12
[prompt] printf -v cmd %q "$cmd"
[prompt] printf -v cmd %q "$cmd"
[prompt] printf -v cmd %q "$cmd"
[prompt] echo "$cmd"
echo\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\$USER\\\\\\\\\\\\\\\'s\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\$HOME\\\\\\\\\\\\\\\ on\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\$HOSTNAME\\\\\\\\\\\\\\\ is\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\$HOME\\\\\\\\\\\\\\\"
# OK, we're ready to go
[prompt] ssh localhost ssh localhost ssh localhost ssh localhost ssh localhost "$cmd"
luser12's $HOME on kgbvax is /home/luser12
Однако имейте в виду, что printf %q
будет использовать экранирующий формат $'...'
кавычек -, который может не поддерживаться удаленной оболочкой (, хотя он поддерживается bash, zsh и т. д. и предположительно должен быть включен в будущая версия стандарта POSIX ).
Bash и ksh93 также имеют typeset -p
(, которые можно использовать как declare -p
в bash ), но они работают только с переменными, а не с литералами:
[prompt] typeset -p foo
declare -- foo="'\"'<>\\\`'\"'''()*@@@@\$\$\$\$\`\`\`\`'''''"
[prompt]
В качестве альтернативы printf %q
более новые версии bash также имеют специальную форму расширения ${var@Q}
:
[bash] echo "${foo@Q}"
''\''"'\''<>\`'\''"'\'''\'''\''()*@@@@$$$$````'\'''\'''\'''\'''\'''