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.