Comando sed em diferentes *nix-like #1

Closed
opened 2026-02-02 09:13:10 -03:00 by devnull · 8 comments

Fui testar o script em um markdown simples, e obtive o erro:
$ ./md2doku teste.md
su: ./md2doku: not found

Dei uma olhada no script, e vi que o problema estava nessa primeira linha:
#!/bin/sed -f

Acontece que nem todos os Unix ou *nix-like tem o comando sed dentro de /bin/sed
Em alguns sistemas esse caminho pode ser diferente, como em alguns Unix e nos BSDs:

$ type sed
sed is /usr/bin/sed

Não da pra usar o /usr/bin/env sed -f, porque o env não aceita comando com parametro (-f)

Pra deixar compatível com todos os Unix e *nix-like, recomendo mudar o script para um shell script full posix compliant em #!/bin/sh
e fazer o sed dentro desse shell script.

Fui testar o script em um markdown simples, e obtive o erro: $ ./md2doku teste.md su: ./md2doku: not found Dei uma olhada no script, e vi que o problema estava nessa primeira linha: #!/bin/sed -f Acontece que nem todos os Unix ou *nix-like tem o comando sed dentro de /bin/sed Em alguns sistemas esse caminho pode ser diferente, como em alguns Unix e nos BSDs: $ type sed sed is /usr/bin/sed Não da pra usar o /usr/bin/env sed -f, porque o env não aceita comando com parametro (-f) Pra deixar compatível com todos os Unix e *nix-like, recomendo mudar o script para um shell script full posix compliant em #!/bin/sh e fazer o sed dentro desse shell script.
Owner

Como o /bin/ é um link simbólico para /usr/bin/, posso simplesmente direcionar o hashbang para o segundo diretório, porque, além de ser aceito pelos BSDs, é também aceito pelo linux.

Como o `/bin/` é um link simbólico para `/usr/bin/`, posso simplesmente direcionar o hashbang para o segundo diretório, porque, além de ser aceito pelos BSDs, é também aceito pelo linux.
Author

Isso não é bem inteiramente verdade ( /bin/ ser um link simbólico para /usr/bin/)

Pode ser verdade em algumas distros linux (ex: debian-based), mas acredito que ainda tenha distros que exista uma separação entre o /bin e /usr/bin

No caso do Debian, isso mudou somente no final de 2023 se não me engano, o que é relativamente recente: https://www.debian.org/releases/bookworm/amd64/release-notes/ch-information.en.html#a-merged-usr-is-now-required

Algumas outras distros adotaram o mesmo padrão que o Debian referente ao /bin/ e /usr/bin/ , mas não é verdade em todas as distros. Ainda em muitas distros linux, /bin/ e /usr/bin/ continuam sendo diretórios distintos.
Slackware por exemplo acredito ser um deles.

Isso não é bem inteiramente verdade ( /bin/ ser um link simbólico para /usr/bin/) Pode ser verdade em algumas distros linux (ex: debian-based), mas acredito que ainda tenha distros que exista uma separação entre o /bin e /usr/bin No caso do Debian, isso mudou somente no final de 2023 se não me engano, o que é relativamente recente: https://www.debian.org/releases/bookworm/amd64/release-notes/ch-information.en.html#a-merged-usr-is-now-required Algumas outras distros adotaram o mesmo padrão que o Debian referente ao /bin/ e /usr/bin/ , mas não é verdade em todas as distros. Ainda em muitas distros linux, /bin/ e /usr/bin/ continuam sendo diretórios distintos. Slackware por exemplo acredito ser um deles.
Owner

@devnull

Então, devemos usar o env sed com parâmetro -f, porque isso deve ser permitido, de acordo com o padrão POSIX: https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/env.html.

@devnull Então, devemos usar o `env sed` com parâmetro `-f`, porque isso deve ser permitido, de acordo com o padrão POSIX: https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/env.html.
Author

@agap

Pelo que eu li na documentação que você passou, isso não é permitido não, e não vai funcionar.
Ainda que o env receba argumentos, se você passar env sed -f , o -f vai ser tratado como um argumento do env, nao do sed.

@agap Pelo que eu li na documentação que você passou, isso não é permitido não, e não vai funcionar. Ainda que o env receba argumentos, se você passar env sed -f , o -f vai ser tratado como um argumento do env, nao do sed.
Owner

@devnull
Estranho... Pode até não funcionar em alguns sistemas irregulares, mas nos posix-compliant essa sintaxe deve — ou, deveria — funcionar, pois no mesmo link mencionado anteriormente a seguinte regra foi expressa:

SYNOPSIS
env [-i] [name=value]... [utility [argument...]]

[...]

OPERANDS
The following operands shall be supported:

name=value
Arguments of the form name= value shall modify the execution environment, and shall be placed into the inherited environment before the utility is invoked.

utility
The name of the utility to be invoked. If the utility operand names any of the special built-in utilities in Special Built-In Utilities, the results are undefined.

argument
A string to pass as an argument for the invoked utility.

@devnull Estranho... Pode até não funcionar em alguns sistemas irregulares, mas nos posix-compliant essa sintaxe deve — ou, _deveria_ — funcionar, pois no mesmo link mencionado anteriormente a seguinte regra foi expressa: > SYNOPSIS > env [-i] [*name=value*]... [_**utility**_ [_**argument...**_]] > [...] > OPERANDS > The following operands **shall be supported**: > *name=value* > Arguments of the form name= value shall modify the execution environment, and shall be placed into the inherited environment before the utility is invoked. > _**utility**_ > The name of the utility to be invoked. If the utility operand names any of the special built-in utilities in Special Built-In Utilities, the results are undefined. > _**argument**_ > A string to pass as an argument **for the invoked _utility_**.
Author

@agap

É que o /usr/bin/env que estamos falando e conforme voce viu na documentação, é invocado direto pela shell.
Então se voce chamar pela shell (ou shell script):
$ /usr/bin/env sed -f

Vai funcionar o comando.

O que não funciona é voce passar o /usr/bin/env sed -f como shebang na primeira linha do script, da forma que voce mencionou anteriormente:
#!/usr/bin/env sed -f

Como shebang não vai funcionar, mas funciona se chamado via shell.
Se colocar o seu shebang aí como
#!/usr/bin/env sed -f

Vai ver que não vai funcionar.
A questão não é o comando env em si, e sim no uso dele como shebang passando esse parametro.

Por via das dúvidas (vai que!), fiz testes agora usando Debian e Slackware. Nenhum deles aceitou como shebang o
#!/usr/bin/env sed -f

@agap É que o /usr/bin/env que estamos falando e conforme voce viu na documentação, é invocado direto pela shell. Então se voce chamar pela shell (ou shell script): $ /usr/bin/env sed -f Vai funcionar o comando. O que não funciona é voce passar o /usr/bin/env sed -f como shebang na primeira linha do script, da forma que voce mencionou anteriormente: #!/usr/bin/env sed -f Como shebang não vai funcionar, mas funciona se chamado via shell. Se colocar o seu shebang aí como #!/usr/bin/env sed -f Vai ver que não vai funcionar. A questão não é o comando env em si, e sim no uso dele como shebang passando esse parametro. Por via das dúvidas (vai que!), fiz testes agora usando Debian e Slackware. Nenhum deles aceitou como shebang o #!/usr/bin/env sed -f
Owner

O env deveria facilitar a vida dos administradores, mas, aparentemente, só criou mais um problema nesse caso. Os da gnu, para sanar esse problema, criaram no Gnu env a flag -S, porém, isso foge do padrão POSIX, embora seja prático. Agora há pouco, fiz um commit procurando sanar a portabilidade e, ao mesmo tempo, conservar o máximo de código original.

O [`env`](https://mail-index.netbsd.org/netbsd-users/2008/11/09/msg002388.html) deveria facilitar a vida dos administradores, mas, aparentemente, só criou mais um problema nesse caso. Os da gnu, para sanar esse problema, criaram no Gnu env a flag `-S`, porém, isso foge do padrão POSIX, embora seja prático. Agora há pouco, fiz um commit procurando sanar a portabilidade e, ao mesmo tempo, conservar o máximo de código original.
Author

Não conheço a flag -S , mas confesso que sinto falta da praticidade algumas vezes.

Deu certo aqui! Vou encerrar a issue!
Valeu!

Não conheço a flag -S , mas confesso que sinto falta da praticidade algumas vezes. Deu certo aqui! Vou encerrar a issue! Valeu!
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
agap/md2doku#1
No description provided.