ZSH: comando di lettura non riuscito all'interno della funzione bash “read: 1: -p: no coprocess”


29

Modificare:

Sembra funzionare all'interno bash. Sembra che il problema sia legato zsh. Se esiste un sito migliore per pubblicare questo problema, fammi sapere.


Sto scrivendo una semplice sceneggiatura che crea una serie di directory. Voglio che l'utente dia una conferma prima di farlo. Sto usando quanto segue come base, ma non riesco a farlo funzionare all'interno di una funzione bash. Se lo metto al di fuori di una funzione, funziona bene. Ecco un esempio isolato:

read.sh

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

codice da questo post SO.

Sourcing il file e / o testrisultati il seguente errore: read:1: -p: no coprocess. Stesso output quando lo inserisco nel mio.bashrc

Modifica ::

@hennes

  1. Voglio che la funzione sia in un file di configurazione, quindi posso chiamarla da qualunque directory (idealmente il mio .bashrc o .zshrc)
  2. Ho corretto la formattazione della prima riga commentata. Il problema esiste ancora inzsh
  3. La versione di Bash è 3.2, ma mi hai aiutato a capire che il problema è con zsh e non bash.

1) Esiste un posto in cui si chiama effettivamente il test funzionale () ? 2) #! /bin/bashcon uno spazio dietro lei shebang? Pensavo che quelli non fossero ammessi? 3) '#! / Usr / bin / env bash' è probabilmente migliore. 4) Quale versione bash? (Ho provato con bash 4.1.10 su FreeBSD e non ho riscontrato errori)
Hennes,

Ho erroneamente taggato la domanda, sto usando zshma non pensavo che ci sarebbe stato conflitto con gli script bash (ho molti altri script simili che funzionano bene). L'ho ricodificato e ho risposto alle tue domande. Grazie per avermi indicato nella giusta direzione!
Nick Tomlin,

Come si avvia il programma? La riga dell'interprete shebang (#!) È necessaria solo se si desidera eseguire il file con ./read.sh. Non è necessario lo si esegue in qualsiasi altro modo o se lo si inserisce in uno script di avvio. E se vuoi eseguirlo in zsh con `zsh ./read.sh ', le righe che iniziano con un # vengono ignorate. Si confondono anche perché danno l'impressione che usi bash quando usi zsh).
Hennes,

@NickTomlin Sai come farlo funzionare senza dover inserire Enter dopo 'y' (sotto ZSH)?
syntagma,

@REACHUS ahimè, io no. In bocca al lupo!
Nick Tomlin,

Risposte:


49

L' –popzione non vuol dire la stessa cosa a bash's readbuilt-in di comando e zsh' s readil comando built-in. In zsh's readdi comando, –pmezzi - Guess - ‘Input vengono letti dal coprocesso.’ Suggerisco che si visualizza il prompt con echoo printf.

Potrebbe anche essere necessario sostituire –n 1con –ko –k 1.


L' zshequivalente di bash's read -p promptè

read "?Here be dragons. Continue?"

Qualsiasi cosa dopo a ?nel primo argomento viene utilizzata come stringa del prompt.

E ovviamente puoi specificare un nome di variabile in cui leggere (e questo potrebbe essere uno stile migliore):

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

(Anche la citazione delle variabili della shell è generalmente una buona idea.)


Grazie per la spiegazione del perché questo non funziona correttamente. Verificherò differenze come questa in futuro.
Nick Tomlin,

Grande spiegazione, grazie! Aveva lo stesso identico problema
iosifv il

8

Questo codice sembra fare quello che vuoi in zsh.
(Nota che la domanda a cui hai fatto riferimento menziona esplicitamente che è per bash).

#! / usr / bin / env zsh

test()
{
  echo -n "Ecco i draghi. Continua?"
  leggi RISPOSTA

  if [[$ REPLY = ~ ^ [Yy] $]]
  poi
    echo "L'hai chiesto ..."
  fi
}

test

Tre commenti:


Grazie per l'aiuto. Ho dato la risposta a @scott per la spiegazione del perché questo non funziona, ma lo snippet che mi hai dato funziona perfettamente.
Nick Tomlin,

1
Solo altre tre cose: questa è stata probabilmente meglio posta su SO (in quanto si tratta di una domanda di programmazione). 2) Non tutte le shell sono compatibili (man zsh restituisce cose diverse per read -p e man bash lo fa. 3) Un'altra soluzione sarebbe quella di cercarej vared -c -p 'domanda rapida'
Hennes

+1 Grazie per avermelo fatto notare. Indirizzerò le future domande incentrate sulla programmazione a SO.
Nick Tomlin,

Nell'ultima riga di questa funzione è necessario aggiungere REPLY=""per cancellare la variabile REPLY. Altrimenti, se riecchi $ REPLY, vedrai che è ancora impostato fino a quando non apri o chiudi il terminale o lo imposti nuovamente.
jasonleonhard,

0

Questa versione consente di avere più di un caso yo Y, noN

  1. Facoltativamente: ripetere la domanda fino a quando non viene fornita una domanda di approvazione

  2. Facoltativamente: ignora qualsiasi altra risposta

  3. Facoltativamente: uscire dal terminale, se lo si desidera

    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=''
    }

Notare anche questo: sull'ultima riga di questa funzione cancellare la variabile REPLY. Altrimenti, se echo $REPLYvedrai che è ancora impostato fino a quando non apri o chiudi il terminale o lo imposti nuovamente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.