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.

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.)


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:


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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.