ZSH: O comando Read falha na função bash “read: 1: -p: no coprocess”

29

Editar:

Parece trabalhar dentro bash. Parece que o problema está relacionado zsh. Se houver um site melhor para publicar esse problema, entre em contato.


Estou escrevendo um script simples que cria uma série de diretórios. Quero que o usuário confirme antes de fazê-lo. Estou usando o seguinte como base, mas não consigo executá-lo em uma função bash. Se eu colocá-lo fora de uma função, ele funciona bem. Aqui está um exemplo isolado:

read.sh

#!/bin/bash
test() {
  read -p "Here be dragons. Continue?" -n 1 -r
  if [[ $REPLY =~ ^[Yy]$ ]]
  then
    echo "You asked for it..."
  fi
}

código desta postagem SO.

Abastecimento de arquivo e / ou testresultados no seguinte erro: read:1: -p: no coprocess. A mesma saída quando a coloco no meu.bashrc

Editar ::

@hennes

  1. Eu quero que a função esteja em um arquivo de configuração, para que eu possa chamá-la de qualquer diretório (idealmente meu .bashrc ou .zshrc)
  2. Corrigi a formatação da primeira linha comentada. O problema ainda existe emzsh
  3. A versão do Bash é 3.2, mas você me ajudou a descobrir que o problema está no zsh e não no bash.
Nick Tomlin
fonte
1) Existe algum lugar onde você realmente chama a função test () ? 2) #! /bin/bashcom um espaço atrás dela shebang? Eu pensei que aqueles não eram permitidos? 3) '#! / Usr / bin / env bash' é provavelmente melhor. 4) Qual versão do bash? (Eu testei com o bash 4.1.10 no FreeBSD e não tem erros)
Hennes
Marquei a pergunta de forma inadequada, estou usando, zshmas não achei que houvesse conflito com os scripts do bash (eu tenho vários outros scripts semelhantes sendo executados corretamente). Marcamos novamente e respondi às suas perguntas. Obrigado por me apontar na direção certa!
22613 Nick Tomlin
Como você inicia o programa? A linha do intérprete shebang (#!) É necessária apenas se você quiser executar o arquivo ./read.sh. Não é necessário executá-lo de qualquer outra maneira ou se você o colocar em um script de inicialização. E se você deseja executá-lo no zsh com `zsh ./read.sh ', as linhas que começam com # são ignoradas. Eles também confundem, pois dão a impressão de que você usa o bash quando usa o zsh).
Hennes 22/02
@NickTomlin Você sabe como fazê-lo funcionar sem precisar colocar Enter depois de 'y' (em ZSH)?
Syntagma
@REACHUS infelizmente, eu não. Boa sorte!
214156 Nick Ellen

Respostas:

49

A –popção não significa a mesma coisa para bash's readbuilt-in de comando e zshde readcomando integrado. Em zsh's readcomando, –pmeios - adivinhe - ‘A entrada é lida a partir do coprocess.’ Eu sugiro que você mostrar o seu tempo com echoou printf.

Você também pode precisar substituir –n 1por –kou –k 1.


O zshequivalente de bash's read -p prompté

read "?Here be dragons. Continue?"

Qualquer coisa após a ?no primeiro argumento é usada como a sequência de prompt.

E é claro que você pode especificar um nome de variável para ler (e isso pode ser um estilo melhor):

read "brave?Here be dragons. Continue?"
if [[ "$brave" =~ ^[Yy]$ ]]
then
    ...
fi

(Citar variáveis ​​do shell geralmente também é uma boa ideia.)

Scott
fonte
Obrigado pela explicação de por que isso não está funcionando corretamente. Vou verificar diferenças como essa no futuro.
22613 Nick Tomlin
Ótima explicação, obrigado! Tinha exatamente o mesmo problema
iosifv 25/01
8

Esse código parece fazer o que você deseja no zsh.
(Observe que a pergunta a que você se refere explicitamente é para bash).

#! / usr / bin / env zsh

teste()
{
  echo -n "Aqui estão os dragões. Continuar?"
  leia RESPOSTA

  se [[$ REPLY = ~ ^ [AA] $]]
  então
    eco "Você pediu ..."
  fi
}

teste

Três comentários:

Hennes
fonte
Obrigado pela ajuda. Dei a resposta ao @scott por causa da explicação de por que isso não está funcionando, mas o snippet que você me deu funciona perfeitamente.
Nick Tomlin
1
Apenas mais três coisas: provavelmente isso foi perguntado no SO (pois é uma questão de programação). 2) Nem todas as conchas são compatíveis (homem zsh retornos coisas diferentes para ler -p seguida, man bash faz 3) Outra solução seria searchj para vared -c -p 'prompt de questão'.
Hennes
+1 Obrigado por me avisar. Dirigirei futuras perguntas centradas em programação para o SO.
22613 Nick Tomlin
Na última linha desta função, você deve adicionar REPLY=""para limpar a variável REPLY. Caso contrário, se você repetir $ REPLY, verá que ele ainda está definido até você abrir ou fechar o terminal ou configurá-lo novamente.
jasonleonhard 26/09
0

Esta versão permite que você tenha mais de um caso you Y, nouN

  1. Opcionalmente: repita a pergunta até que uma pergunta de aprovação seja fornecida

  2. Opcionalmente: ignore qualquer outra resposta

  3. Opcionalmente: saia do terminal se desejar

    confirm() {
        echo -n "Continue? y or n? "
        read REPLY
        case $REPLY in
        [Yy]) echo 'yup y' ;; # you can change what you do here for instance
        [Nn]) echo 'nope n' ;;
        # Here are a few optional options to choose between
        # Any other answer:
    
        # 1. Repeat the question
        *) confirm ;;
    
        # 2. ignore
        # *) ;;
    
        # 3. Exit terminal
        # *) exit ;;
    
        esac
        # REPLY=''
    }

Observe também: Na última linha desta função, limpe a variável REPLY. Caso contrário, se você echo $REPLYver que ele ainda está definido até você abrir ou fechar o terminal ou configurá-lo novamente.

jasonleonhard
fonte