ZSH: Polecenie odczytu nie działa w funkcji bash „czytaj: 1: -p: brak koprocesu”

17

Edytować:

Wydaje się działać wewnątrz bash. Wygląda na to, że problem jest związany z zsh. Jeśli jest lepsza strona do opublikowania tego problemu, daj mi znać.


Piszę prosty skrypt, który tworzy serię katalogów. Chcę, aby użytkownik dał potwierdzenie, zanim to zrobię. Używam następujących zasad jako podstawy, ale nie wydaje mi się, aby działał w funkcji bash. Jeśli umieściłem go poza funkcją, działa dobrze. Oto przykład:

read.sh

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

kod z to SO post.

Pozyskiwanie pliku i / lub test powoduje następujący błąd: read:1: -p: no coprocess. To samo wyjście, gdy umieściłem go w moim .bashrc

Edytować: :

@hennes

  1. Chcę, aby funkcja znajdowała się w pliku konfiguracyjnym, więc mogę go wywołać z dowolnego katalogu (najlepiej mojego .bashrc lub .zshrc)
  2. Poprawiłem formatowanie pierwszej skomentowanej linii. Problem nadal istnieje zsh
  3. Wersja Bash to 3.2, ale pomogłeś mi się zorientować, że problem dotyczy zsh, a nie basha.
Nick Tomlin
źródło
1) Czy jest jakieś miejsce, w którym faktycznie wywołujesz funkcję test() ? 2) #! /bin/bash z przestrzenią za nią shebang? Myślałem, że to nie jest dozwolone? 3) '#! / Usr / bin / env bash' jest prawdopodobnie lepszy. 4) Która wersja basha? (Testowałem z bash 4.1.10 na FreeBSD i nie miałem żadnych błędów)
Hennes
Nieprawidłowo otagowałem pytanie, używam zsh ale nie myślałem, że będzie konflikt ze skryptami bash (mam kilka innych podobnych skryptów działających poprawnie). Odznaczyłem go i odpowiedziałem na twoje pytania. Dzięki za wskazanie mi właściwego kierunku!
Nick Tomlin
Jak uruchomić program? Linia shebang (#!) Interpreter` jest potrzebna tylko wtedy, gdy chcesz wykonać plik za pomocą ./read.sh. Nie jest potrzebny, jeśli uruchomisz go w inny sposób lub umieścisz w skrypcie startowym. A jeśli chcesz go uruchomić w zsh za pomocą `zsh ./read.sh ', linie zaczynające się od # zostaną zignorowane. Mylą się także, ponieważ sprawiają wrażenie, że używasz basha, gdy używasz zsh).
Hennes
@NickTomlin Czy wiesz, jak sprawić, by działał bez konieczności wprowadzania Enter po 'y' (pod ZSH)?
syntagma
@ REACHUS niestety nie. Powodzenia!
Nick Tomlin

Odpowiedzi:

32

The –p opcja nie oznacza tego samego bash S read wbudowane polecenie i zsh S read wbudowane polecenie. W zsh S read dowództwo, –p oznacza –– zgadnij –– „Dane wejściowe są odczytywane z koprocesu”. Sugeruję, abyś wyświetlał swój monit za pomocą echo lub printf.

Może również zajść potrzeba wymiany –n 1 z –k lub –k 1.


The zsh odpowiednik bash jest read -p prompt jest

read "?Here be dragons. Continue?"

Wszystko po ? w pierwszym argumencie jest używany jako łańcuch zachęty.

I oczywiście możesz podać nazwę zmiennej do wczytania (a może to być lepszy styl):

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

(Cytowanie zmiennych powłoki jest również dobrym pomysłem.)

Scott
źródło
Dziękujemy za wyjaśnienie, dlaczego to nie działa prawidłowo. W przyszłości sprawdzę różnice takie jak ta.
Nick Tomlin
Świetne wyjaśnienie, dziękuję! Miał dokładnie ten sam problem
iosifv
8

Ten kod wydaje się robić w Zsh to, co chcesz.
(Zauważ, że pytanie, do którego odnosiłeś się wyraźnie, wspomina, że ​​dotyczy basha).

#!/usr/bin/env zsh

test()
{
  echo -n "Here be dragons. Continue?"
  read REPLY

  if [[ $REPLY =~ ^[Yy]$ ]]
  then
    echo "You asked for it..."
  fi
}

test

Trzy komentarze:

Hennes
źródło
Dziękuję za pomoc. Odpowiedziałem na @scott z powodu wyjaśnienia, dlaczego to nie działa, ale fragment, który mi podałeś, działa idealnie.
Nick Tomlin
1
Jeszcze tylko trzy rzeczy: najprawdopodobniej najlepiej zapytano o SO (ponieważ jest to pytanie programistyczne). 2) Nie wszystkie powłoki są kompatybilne (man zsh zwraca różne rzeczy do odczytu -p, a następnie man bash. 3) Innym rozwiązaniem byłoby searchj dla vared -c -p 'prompt question'
Hennes
+1 Dzięki za poinformowanie mnie. Skieruję przyszłe pytania programowo-centryczne do SO.
Nick Tomlin