
Я только что столкнулся со следующим
grep -h ^ID= /etc/*-release
python -c 'from os import system; system("echo hello; echo $_")'
для RHEL это дает то, что я ожидаю ( $_
расширяется до hello
):
$ grep -h ^ID= /etc/*-release
ID="rhel"
$ python -c 'from os import system; system("echo hello; echo $_")'
hello
hello
но для Ubuntu (WSL) нет:
$ grep -h ^ID= /etc/*-release
ID=ubuntu
$ python -c 'from os import system; system("echo hello; echo $_")'
hello
/usr/bin/python
почему это?
решение1
os.system
делегирует функцию C system()
:
os.system(command)
Выполнить команду (строку) в подоболочке. Это реализуется вызовом стандартной функции C
system()
который в Linux определяется как:
int system(const char *command);
Библиотечная
system()
функция используетсяfork(2)
для создания дочернего процесса, который выполняет команду оболочки, указанную вcommand
usingexecl(3)
следующим образом:execl("/bin/sh", "sh", "-c", command, (char *) NULL);
В RHEL sh
это bash
, а в Ubuntu это dash
.
$_
не определено в dash
, это функционал bash, отсюда и несоответствие.
В Ubuntu/Debian вы можете установить bash-as-sh sudo dpkg-reconfigure dash
, выбрав «Нет» в диалоговом окне.