ZSH: Команда читання не вдається в межах функції bash "read: 1: -p: немає coprocess"


29

Редагувати:

Здається, працює всередині bash. Здається, проблема пов’язана zsh. Якщо є кращий сайт для розміщення цього питання, дайте мені знати.


Я пишу простий сценарій, який створює низку каталогів. Я хочу, щоб користувач надавав підтвердження до цього. Я використовую наступне як основу, але, здається, не можу змусити його працювати в рамках функції bash. Якщо я поставив його поза функцією, він працює добре. Ось окремий приклад:

read.sh

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

код з цієї публікації SO

Sourcing файлу і / або testрезультатів в наступній помилку: read:1: -p: no coprocess. Той самий вихід, коли я розміщую його в своєму.bashrc

Редагувати :

@hennes

  1. Я хочу, щоб функція знаходилась у конфігураційному файлі, тому я можу викликати її з будь-якого каталогу (в ідеалі мого .bashrc або .zshrc)
  2. Я виправив форматування першого коментованого рядка. Проблема все ще існує вzsh
  3. Версія Bash - 3.2, але ви допомогли мені зрозуміти, що проблема полягає в zsh, а не bash.

1) Чи є місце, де ви насправді викликаєте тест функції () ? 2) #! /bin/bashз пробілом позаду shebang? Я думав, що їх не дозволяють? 3) "#! / Usr / bin / env bash", мабуть, краще. 4) Яка версія bash? (Я тестував bash 4.1.10 на FreeBSD і не мав помилок)
Hennes

Я неправильно позначив це питання, я використовую, zshале не думав, що буде конфлікт із bash-скриптами (у мене є кілька інших подібних сценаріїв, які працюють у порядку). Я переназначив це і відповів на ваші запитання. Дякую, що вказали на мене в правильному напрямку!
Нік Томлін

Як запустити програму? Рядок інтерпретатора shebang (#!) Потрібен лише у тому випадку, якщо ви хочете виконати файл із допомогою ./read.sh. Це не потрібно, ви запускаєте його будь-яким іншим способом або якщо ставите його в сценарій запуску. І якщо ви хочете запустити його в zsh з `zsh ./read.sh ', тоді рядки, що починаються з #, ігноруються. Вони також плутаються, оскільки створюють враження, що ви використовуєте bash, коли використовуєте zsh).
Геннес

@NickTomlin Чи знаєте ви, як змусити його працювати, не вводячи Enter після 'y' (під ZSH)?
синтагма

@REACHUS на жаль, я ні. Удачі!
Нік Томлін

Відповіді:


50

–pВаріант не означає , що те ж саме з bash«S readвбудована команда і zsh» s readвбудовану команду. У команді zsh' означає - здогадайтеся - - «Введення зчитується з копроцесу». Я пропоную вам відобразити своє запит з або .read–pechoprintf

Вам також може знадобитися замінити –n 1на –kабо –k 1.


zshЕквівалент bash«и read -p promptє

read "?Here be dragons. Continue?"

Що-небудь після ?першого аргументу використовується як рядок підказок.

І звичайно, ви можете вказати ім'я змінної, яку слід читати (і це може бути кращим стилем):

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

(Цитування змінних оболонок, як правило, також є хорошою ідеєю.)


Дякую за пояснення, чому це не працює належним чином. Я буду перевіряти подібні відмінності в майбутньому.
Нік Томлін

Чудове пояснення, дякую! Мав точно таку проблему
iosifv

8

Цей код, здається, робить те, що ви хочете в zsh.
(Зауважте, що питання, про яке ви посилалися, прямо згадує, це стосується баш).

#! / usr / bin / env zsh

тест ()
{
  echo -n "Тут будуть дракони. Продовжувати?"
  читати ЗАВДАННЯ

  якщо [[$ ЗАВДАННЯ = ~ ^ [Yy] $]]
  потім
    відлуння "Ви просили про це ..."
  фі
}

тест

Три коментарі:


Дякую за твою допомогу. Я відповів на @scott через пояснення, чому це не працює, але фрагмент, який ви мені дали, працює чудово.
Нік Томлін

1
Ще три речі: це, мабуть, найкраще було задано на SO (оскільки це питання програмування). 2) Не всі оболонки сумісні (man zsh повертає різні речі для читання -p, тоді робить man bash. 3) Іншим рішенням буде пошук searchj для vared -c -p 'швидке запитання'
Hennes

+1 Дякую, що повідомили мені. Я буду скеровувати майбутні питання, орієнтовані на програмування, до SO.
Нік Томлін

В останньому рядку цієї функції слід додати, REPLY=""щоб очистити змінну REPLY. В іншому випадку, якщо ви відлучите $ REPLY, ви побачите, що він все ще встановлений, поки ви не відкриєте або закриєте свій термінал або не встановите його знову.
Jasonleonhard

0

Ця версія дозволяє мати кілька випадків yабо Y, nабоN

  1. Необов’язково: Повторюйте питання, поки не буде надано схвалення

  2. За бажанням: ігноруйте будь-яку іншу відповідь

  3. За бажанням: Вийдіть з терміналу, якщо хочете

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

Зверніть увагу і на це: в останньому рядку цієї функції очистіть змінну REPLY. В іншому випадку, якщо ви echo $REPLYпобачите, він все ще встановлений, поки ви не відкриєте або закриєте свій термінал або не встановите його знову.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.