A função system("cmd")
de Perl geralmente bifurca um processo e, no processo filho, executa o shell do sistema (geralmente /bin/sh
) com argumentos, ["sh", "-c", "cmd"]
, para ter sh
parse e executar essa linha de comando do shell.
Como uma otimização, às vezes pode ficar sem uma chamada de shell, se cmd
não contiver nenhum meta-caractere de shell (como caractere de citação ou caracteres globbing ou coisas como ;
, &&
...) diferente de espaço e tabulação, mas aqui temos metacaracteres do shell, pois temos um *
.
Então, esse ls -U -1 dir/*
será interpretado pelo shell do sistema.
É o shell que expande dir/*
para uma lista de arquivos correspondentes passados para ls
, então o modo como é feito depende do shell.
Em um terminal, você normalmente executa seu shell de login, que geralmente não é /bin/sh
. Também (como anotado por peterph ), esse shell, uma vez que é executado interativamente, normalmente lerá arquivos de configuração como ~/.zshrc
(se o shell for zsh
) onde algumas configurações podem afetar a forma como o globbing é feito. / p>
Por exemplo:
Meu shell é zsh
e eu tenho um setopt dotglob
no meu ~/.zshrc
, então:
$ echo *
.a d é f
Sem ler o ~/.zshrc
:
$ zsh -c 'echo *'
d é f
$ LC_ALL=C zsh -c 'echo *'
d f é
Você notará que zsh
respeita a localidade ao classificar a lista.
$ sh -c 'echo *'
d f é
sh
(que no meu caso é o Debian ash
) não honra a localidade e classifica como se estivesse na localidade C.
Se você quiser que perl
do system()
interprete a linha de comando com um determinado shell, você pode escrevê-lo:
system("zsh", "-c", "cmd");
Quando ultrapassado esse argumento, perl
' system()
nunca chama implicitamente um shell, então, acima, ele bifurca um processo no qual ele executa /bin/zsh
com ["zsh", "-c", "cmd"]
como argumentos.