How can I print out the delimiter character and allow user to edit line while reading standard input?

Lety

I'm trying to write a simple script that read from standard input, using ; character as delimiter to terminate the input line and that allows user to edit line.

Here is my test script:

#!/bin/bash

while true; do

  read -e -d ";" -t 180 -p "><> " srcCommand

  if [ $? != 0 ]; then
    echo "end;"
    echo ""
    exit 0
  fi
  case "$srcCommand" in
    startApp)
       echo "startApp command";;
    stopApp)
       echo "stopApp command";;
    end)
       echo ""
       exit 0
       ;;
    *)
       echo "unknown command";;
  esac
done

This works but doesn't print the delimiter ';' char:

# bash test.sh
><> startApp
startApp command
><> stopApp
stopApp command
><> end

If I remove -e option it prints out ; but user can't correct his mistake using backspace character and echoed strings are just right after the delimiter:

# bash test.sh
><> startApp;startApp command
><> stopApp;stopApp command
><> end;

How can I print out the delimiter character and allow user to edit line while reading standard input?

This is the expected behavior:

# bash test.sh
><> startApp;
startApp command
><> stopApp;
stopApp command
><> end;

Thanks

Stéphane Chazelas

I'd use zsh where the line editor has many more capabilities and is a lot more customizable:

#! /bin/zsh -
insert-and-accept() {
  zle self-insert
  # RBUFFER= # to discard everything on the right
  zle accept-line
}
zle -N insert-and-accept
bindkey ";" insert-and-accept
bindkey "^M" self-insert
vared -p "><> " -c srcCommand

With bash-4.3 or above, you can do something similar with a hack like:

# bind ; to ^Z^C (^Z, ^C otherwide bypass the key binding when entered
# on the keyboard). Redirect stderr to /dev/null to discard the
# useless warning
bind '";":"\32\3"' 2> /dev/null

# new widget that inserts ";" at the end of the buffer.
# If we did bind '";":";\3"', readline would loop indefinitely
add_semicolon() {
  READLINE_LINE+=";"
  ((READLINE_POINT++))
}
# which we bind to ^Z
bind -x '"\32":add_semicolon' 2> /dev/null

# read until the ^C
read -e -d $'\3' -t 180 -p '><> ' srcCommand

Note that in that version, the ; is always inserted at the end of the input buffer, not at the current cursor position. Change the add_semicolon to:

add_semicolon() {
  READLINE_LINE="${READLINE_LINE:0:READLINE_POINT++};"
}

If you want it inserted at the cursor and everything on the right discarded. Or:

add_semicolon() {
  READLINE_LINE="${READLINE_LINE:0:READLINE_POINT};${READLINE_LINE:READLINE_POINT}"
  READLINE_POINT=${#READLINE_LINE}
}

if you want to insert it at the cursor but want to preserve what's on the right like in the zsh approach.

If you don't want the ; in $srcCommand, you can always strip it afterwards with srcCommand="${srcComman//;}" for instance, but you'd need to insert it in the widget for it to be displayed by zle/readline.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

bash: Prompting for user input while reading file

분류에서Dev

How can I edit a line in a file opened with FileSystemObject in VBA?

분류에서Dev

edit a file line by line interactively from user input in python

분류에서Dev

How can I print out session message in Laravel?

분류에서Dev

How can I print the output of pv each on a new line as it changes?

분류에서Dev

how to print out the user number input with the result instead of showing only result?

분류에서Dev

How to allow user input of numbers and operators?

분류에서Dev

How can I invoke a user switch from the command line?

분류에서Dev

Zenity question - how can I use user input?

분류에서Dev

How can I change uipanel dimensions by using user input?

분류에서Dev

How to print out to the same line, overriding previous line?

분류에서Dev

How can I use awk to create a variable that is used in the next line edit

분류에서Dev

How can I end the cell's edit and submit the new value when the user clicks on another control?

분류에서Dev

How can I skip even/odd rows while reading a csv file?

분류에서Dev

how can i use \d in php pdo to print the tables out of a database in progress?

분류에서Dev

How can I print out the main lemma of a WordNet synset? Python NLTK

분류에서Dev

How to accept user input inside while loop

분류에서Dev

How to count the number of character in a comma separated line where commas within delimiter are not to be counted as separate?

분류에서Dev

How to wrap two line into single line with delimiter

분류에서Dev

reading input from user in a loop

분류에서Dev

How can I store avatar(image file) through Auth/RegisterController while user registration?

분류에서Dev

How do I edit previous lines in a multiple line command in Bash?

분류에서Dev

Shared Preferences - how long do they exist and can user edit them?

분류에서Dev

How Can I tell if the current user is Admin from Windows Command Line

분류에서Dev

How can i restrict user from not selecting other file types using input type file with react and typescript?

분류에서Dev

How can I preform a GET request when user input equals current time?

분류에서Dev

How can I match a user id value from a form input to records in my database?

분류에서Dev

How can i compare string and character types?

분류에서Dev

How do I reprompt to allow user to continue converting values?

Related 관련 기사

  1. 1

    bash: Prompting for user input while reading file

  2. 2

    How can I edit a line in a file opened with FileSystemObject in VBA?

  3. 3

    edit a file line by line interactively from user input in python

  4. 4

    How can I print out session message in Laravel?

  5. 5

    How can I print the output of pv each on a new line as it changes?

  6. 6

    how to print out the user number input with the result instead of showing only result?

  7. 7

    How to allow user input of numbers and operators?

  8. 8

    How can I invoke a user switch from the command line?

  9. 9

    Zenity question - how can I use user input?

  10. 10

    How can I change uipanel dimensions by using user input?

  11. 11

    How to print out to the same line, overriding previous line?

  12. 12

    How can I use awk to create a variable that is used in the next line edit

  13. 13

    How can I end the cell's edit and submit the new value when the user clicks on another control?

  14. 14

    How can I skip even/odd rows while reading a csv file?

  15. 15

    how can i use \d in php pdo to print the tables out of a database in progress?

  16. 16

    How can I print out the main lemma of a WordNet synset? Python NLTK

  17. 17

    How to accept user input inside while loop

  18. 18

    How to count the number of character in a comma separated line where commas within delimiter are not to be counted as separate?

  19. 19

    How to wrap two line into single line with delimiter

  20. 20

    reading input from user in a loop

  21. 21

    How can I store avatar(image file) through Auth/RegisterController while user registration?

  22. 22

    How do I edit previous lines in a multiple line command in Bash?

  23. 23

    Shared Preferences - how long do they exist and can user edit them?

  24. 24

    How Can I tell if the current user is Admin from Windows Command Line

  25. 25

    How can i restrict user from not selecting other file types using input type file with react and typescript?

  26. 26

    How can I preform a GET request when user input equals current time?

  27. 27

    How can I match a user id value from a form input to records in my database?

  28. 28

    How can i compare string and character types?

  29. 29

    How do I reprompt to allow user to continue converting values?

뜨겁다태그

보관