ZSH: Lệnh đọc không thành công trong hàm bash. Đọc: 1: -p: không có coprocess


29

Biên tập:

Có vẻ để làm việc trong bash. Có vẻ như vấn đề có liên quan đến zsh. Nếu có một trang web tốt hơn để đăng vấn đề này trên cho tôi biết.


Tôi đang viết một kịch bản đơn giản tạo ra một loạt các thư mục. Tôi muốn người dùng xác nhận trước khi tôi làm như vậy. Tôi đang sử dụng những điều sau đây làm cơ sở, nhưng dường như không thể làm cho nó chạy trong một hàm bash. Nếu tôi đặt nó bên ngoài một chức năng, nó hoạt động tốt. Đây là một ví dụ cô lập:

đọc

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

mã từ bài SO này .

Tìm nguồn tệp và / hoặc testkết quả trong lỗi sau : read:1: -p: no coprocess. Cùng một đầu ra khi tôi đặt nó trong.bashrc

Chỉnh sửa ::

@hennes

  1. Tôi muốn hàm này nằm trong một tệp cấu hình, vì vậy tôi có thể gọi nó từ bất kỳ thư mục nào (lý tưởng là .bashrc hoặc .zshrc)
  2. Tôi đã sửa định dạng của dòng nhận xét đầu tiên. Vấn đề vẫn còn tồn tại trongzsh
  3. Phiên bản Bash là 3.2, nhưng bạn đã giúp tôi nhận ra rằng vấn đề là do zsh chứ không phải bash.

1) Có nơi nào bạn thực sự gọi hàm test () không? 2) #! /bin/bashvới một không gian phía sau cô shebang? Tôi nghĩ những người không được phép? 3) '#! / Usr / bin / env bash' có lẽ tốt hơn. 4) Phiên bản bash nào? (Tôi đã thử nghiệm với bash 4.1.10 trên FreeBSD và không có lỗi)
Hennes

Tôi đã gắn thẻ câu hỏi không chính xác, tôi đang sử dụng zshnhưng không nghĩ rằng sẽ có xung đột với các tập lệnh bash (tôi có một số tập lệnh tương tự khác đang chạy ổn). Tôi đã thử lại và trả lời câu hỏi của bạn. Cám ơn đã chỉ tôi hướng đi đúng!
Nick Tomlin

Làm thế nào để bạn bắt đầu chương trình? Dòng thông dịch shebang (#!) Chỉ cần thiết nếu bạn muốn thực thi tệp với ./read.sh. Không cần thiết, bạn chạy nó theo bất kỳ cách nào khác hoặc nếu bạn đặt nó trong một kịch bản khởi động. Và nếu bạn muốn chạy nó trong zsh với `zsh ./read.sh 'thì các dòng bắt đầu bằng # bị bỏ qua. Họ cũng nhầm lẫn vì họ cho ấn tượng rằng bạn sử dụng bash khi bạn sử dụng zsh).
Hennes

@NickTomlin Bạn có biết làm thế nào để nó hoạt động mà không phải đặt Enter sau 'y' (dưới ZSH) không?
cú pháp

@REACHUS than ôi, tôi thì không. Chúc may mắn!
Nick Tomlin

Câu trả lời:


49

Các –ptùy chọn không có nghĩa là điều tương tự để bash's readbuilt-in lệnh và zsh' s readbuilt-in lệnh. Trong zsh's readlệnh, –pphương tiện - đoán - ‘Input được đọc từ coprocess.’ Tôi đề nghị bạn nên hiển thị dấu nhắc của bạn với echohoặc printf.

Bạn cũng có thể cần phải thay thế –n 1bằng –khoặc –k 1.


Các zshtương đương với bash's read -p prompt

read "?Here be dragons. Continue?"

Bất cứ điều gì sau một ?đối số đầu tiên được sử dụng làm chuỗi nhắc nhở.

Và tất nhiên bạn có thể chỉ định một tên biến để đọc vào (và đây có thể là phong cách tốt hơn):

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

(Trích dẫn các biến shell nói chung cũng là một ý tưởng tốt.)


Cảm ơn đã giải thích lý do tại sao điều này không hoạt động đúng. Tôi sẽ kiểm tra sự khác biệt như thế này trong tương lai.
Nick Tomlin

Giải thích tuyệt vời, cảm ơn! Có cùng một vấn đề
iosifv

8

Mã này dường như làm những gì bạn muốn trong zsh.
(Lưu ý rằng câu hỏi mà bạn đề cập đến rõ ràng đề cập đến nó là dành cho bash).

#! / usr / bin / env zsh

kiểm tra()
{
  echo -n "Đây là rồng. Tiếp tục?"
  đọc TRẢ LỜI

  nếu [[$ REPLY = ~ ^ [Yy] $]]
  sau đó
    echo "Bạn đã yêu cầu nó ..."
  fi
}

kiểm tra

Ba ý kiến:


Cảm ơn sự giúp đỡ của bạn. Tôi đã đưa ra câu trả lời cho @scott vì lý giải tại sao điều này không hoạt động, nhưng đoạn trích bạn đã cho tôi hoạt động hoàn hảo.
Nick Tomlin

1
Chỉ ba điều nữa: Điều này có lẽ được hỏi tốt nhất trên SO (vì đây là một câu hỏi lập trình). 2) Không phải tất cả các shell đều tương thích (man zsh trả về các nội dung khác nhau để đọc -p thì man bash cũng vậy. 3) Một giải pháp khác là tìm kiếm cho vared -c -p 'câu hỏi nhanh'
Hennes

+1 Cảm ơn đã cho tôi biết. Tôi sẽ gửi câu hỏi trung tâm lập trình trong tương lai tới SO.
Nick Tomlin

Trên dòng cuối cùng của chức năng này, bạn nên thêm REPLY=""để xóa biến REPLY. Mặt khác, nếu bạn lặp lại $ REPLY, bạn sẽ thấy nó vẫn được đặt cho đến khi bạn mở hoặc đóng thiết bị đầu cuối hoặc đặt lại.
jasonleonhard

0

Phiên bản này cho phép bạn có nhiều hơn một trường hợp yhoặc Y, nhoặcN

  1. Tùy chọn: Lặp lại câu hỏi cho đến khi câu hỏi phê duyệt được cung cấp

  2. Tùy chọn: Bỏ qua bất kỳ câu trả lời khác

  3. Tùy chọn: Thoát khỏi thiết bị đầu cuối nếu bạn muốn

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

Cũng lưu ý điều này: Trên dòng cuối cùng của chức năng này, hãy xóa biến REPLY. Mặt khác, nếu bạn echo $REPLYsẽ thấy nó vẫn được đặt cho đến khi bạn mở hoặc đóng thiết bị đầu cuối của bạn hoặc đặt lại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.