ZSH: Perintah baca gagal di dalam fungsi bash "read: 1: -p: no coprocess"

29

Edit:

Tampaknya bekerja di dalam bash. Tampaknya masalah ini berkaitan dengan zsh. Jika ada situs yang lebih baik untuk mengirim masalah ini, beri tahu saya.


Saya sedang menulis skrip sederhana yang menciptakan serangkaian direktori. Saya ingin pengguna memberikan konfirmasi sebelum saya melakukannya. Saya menggunakan berikut ini sebagai dasar, tetapi tampaknya tidak bisa menjalankannya dalam fungsi bash. Jika saya letakkan di luar fungsi itu berfungsi dengan baik. Berikut ini adalah contoh yang terisolasi:

baca.sh

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

kode dari pos SO ini .

Sourcing file dan / atau testhasil dalam kesalahan berikut: read:1: -p: no coprocess. Output yang sama ketika saya menempatkannya di.bashrc

Edit ::

@hennes

  1. Saya ingin fungsi berada dalam file konfigurasi, jadi saya bisa memanggilnya dari direktori apa pun (idealnya .bashrc atau .zshrc)
  2. Saya telah mengoreksi pemformatan baris komentar pertama. Masalah masih ada dizsh
  3. Versi Bash adalah 3.2, tetapi Anda telah membantu saya mengetahui bahwa masalahnya ada pada zsh dan bukan bash.
Nick Tomlin
sumber
1) Apakah ada tempat di mana Anda benar-benar memanggil tes fungsi () ? 2) #! /bin/bashdengan ruang di belakang dia shebang? Saya pikir itu tidak diizinkan? 3) '#! / Usr / bin / env bash' mungkin lebih baik. 4) Versi bash mana? (Saya diuji dengan bash 4.1.10 di FreeBSD dan tidak mendapatkan kesalahan)
Hennes
Saya salah menandai pertanyaan, saya menggunakan zshtetapi tidak berpikir bahwa akan ada konflik dengan skrip bash (saya punya beberapa skrip serupa yang berjalan dengan baik). Saya telah mengulanginya, dan menjawab pertanyaan Anda. Terima kasih telah mengarahkan saya ke arah yang benar!
Nick Tomlin
Bagaimana Anda memulai program? Baris interpreter` shebang (#!) Hanya diperlukan jika Anda ingin mengeksekusi file tersebut ./read.sh. Anda tidak perlu menjalankannya dengan cara lain atau jika Anda memasukkannya ke skrip startup. Dan jika Anda ingin menjalankannya di zsh dengan `zsh ./read.sh 'maka baris yang dimulai dengan # diabaikan. Mereka juga bingung karena mereka memberi kesan bahwa Anda menggunakan bash ketika Anda menggunakan zsh).
Hennes
@NickTomlin Apakah Anda tahu cara membuatnya bekerja tanpa harus memasukkan Enter setelah 'y' (di bawah ZSH)?
syntagma
@REACHUS sayang sekali, saya tidak. Semoga berhasil!
Nick Tomlin

Jawaban:

49

The –ppilihan tidak berarti hal yang sama untuk bash's readbuilt-in command dan zsh' s readbuilt-in perintah. Dalam zsh's readperintah, –pberarti - menebak - ‘Input dibaca dari coprocess itu.’ Saya menyarankan agar Anda menampilkan prompt Anda dengan echoatau printf.

Anda mungkin juga perlu mengganti –n 1dengan –katau –k 1.


The zshsetara dengan bash's read -p promptis

read "?Here be dragons. Continue?"

Apa pun setelah ?dalam argumen pertama digunakan sebagai string prompt.

Dan tentu saja Anda dapat menentukan nama variabel untuk dibaca (dan ini mungkin gaya yang lebih baik):

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

(Mengutip variabel shell umumnya adalah ide yang bagus juga.)

Scott
sumber
Terima kasih atas penjelasan mengapa ini tidak berfungsi dengan baik. Saya akan memeriksa perbedaan seperti ini di masa depan.
Nick Tomlin
Penjelasan yang bagus, terima kasih! Punya masalah yang sama persis
iosifv
8

Kode ini tampaknya melakukan apa yang Anda inginkan di zsh.
(Perhatikan bahwa pertanyaan yang Anda rujuk secara eksplisit menyebutkan itu untuk bash).

#! / usr / bin / env zsh

uji()
{
  echo -n "Ini naga. Lanjutkan?"
  baca REPLY

  jika [[$ REPLY = ~ ^ [Yy] $]]
  kemudian
    gema "Anda memintanya ..."
  fi
}

uji

Tiga komentar:

Hennes
sumber
Terima kasih untuk bantuannya. Saya telah memberikan jawaban untuk @scott karena penjelasan mengapa ini tidak berfungsi, tetapi cuplikan yang Anda berikan berfungsi dengan baik.
Nick Tomlin
1
Hanya tiga hal lagi: Ini mungkin paling baik ditanyakan pada SO (karena ini adalah pertanyaan pemrograman). 2) Tidak semua shell kompatibel (man zsh mengembalikan hal-hal yang berbeda untuk dibaca -p kemudian man bash. 3) Solusi lain adalah mencari dengan 'pertanyaan cepat' vared -c -p
Hennes
+1 Terima kasih telah memberi tahu saya. Saya akan mengarahkan pertanyaan pemrograman-sentris masa depan ke SO.
Nick Tomlin
Pada baris terakhir dari fungsi ini, Anda harus menambahkan REPLY=""untuk menghapus variabel REPLY. Kalau tidak, jika Anda menggemakan $ REPLY, Anda akan melihatnya masih diatur sampai Anda membuka atau menutup terminal Anda atau mengaturnya lagi.
jasonleonhard
0

Versi ini memungkinkan Anda memiliki lebih dari satu kasing yatau Y, natauN

  1. Opsional: Ulangi pertanyaan sampai pertanyaan yang disetujui diberikan

  2. Secara opsional: Abaikan jawaban lain

  3. Opsional: Keluar dari terminal jika Anda mau

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

Perhatikan ini juga: Pada baris terakhir dari fungsi ini, hapus variabel REPLY. Kalau tidak, jika Anda echo $REPLYakan melihatnya masih diatur sampai Anda membuka atau menutup terminal Anda atau mengaturnya lagi.

jasonleonhard
sumber