Tenho esse script e parece que ele printf '%s\0%s\0'
sai com o código 1 e não consigo entender o porquê.
Eu até forcei a usar o bash versão 5.2 - mesmos resultados.
Aqui está um script de exemplo e sua saída
#!/usr/bin/env bash
echo $BASH_VERSION
set -x
set -Eeuo pipefail
function prompt_creds {
local username password
read -rp "username " username
read -rsp "password " password
printf '%s\0%s\0' "${username}" "${password}"
}
function main() {
IFS=$'\0' read -r username password < <(prompt_creds )
echo "name name is ${username}" "my password is ${password}"
}
main
uso e saída
./sample.sh
3.2.57(1)-release
+ set -Eeuo pipefail
+ main
+ IFS=
+ read -r username password
++ prompt_creds
++ local username password
++ read -rp 'username ' username
username user
++ read -rsp 'password ' password
password ++ printf '%s\0%s\0' user pass
bash-5.2$ echo $?
1
Eu até tentei executá-lo simplesmente na CLI e funcionou:
bash-5.2$ IFS=$'\0' read -r u p < <(printf '%s\0%s\0' user pass)
bash-5.2$ echo $u $p
userpass
O bash não suporta um caractere NUL em uma variável (AFAIK, apenas o zsh suporta).
IFS=$'\0'
Na verdade, defineIFS
como vazio e com essa configuração,read -r u p
é fornecida uma entrada contendo usuário-NUL-senha-NUL:atribui
userpass
(com os NULs descartados) a vocênão atribui nada (vazio) a p
define o status de saída 1, porque
read
sem-d
espera uma linha (terminada por uma nova linha), e comset -e
na verdade isso faz com que vocêmain
saia imediatamenteSeu último teste NÃO funcionou de fato; se u=user e p=pass como você pretendia, ele teria exibido
user pass
notuserpass
. E seu shell interativo não tinha,set -e
então ele ignorou o status de saída.Tente em vez disso
{ read -rd '' u; read -rd '' p; } < <(prompt_creds)
Como alternativa, use nova linha (que não pode estar em nenhum dos seus valores) como separador:
Mas isso ainda define o status 1, abortando if
set -e
; para corrigir isso, adicione\0
ao final ou use o padrão set-e-nots:mayfail || true
mayfail || :
! mayfail
if mayfail; then :; fi
. Ou, é claro, simplesmente não useset -e
em primeiro lugar.Você pode evitar usar
printf
neste caso: