25

I have problem executing a simple script in bash. The script is like this:

#! /bin/sh

read -p 'press  [ENTER]  to continue deleting line'
sudo sed -ie '$d' /home/hpccuser/.profile

and when I execute the script with ./script the output is like this:

press  [ENTER]  to continue deleting line./script: 3: read: arg count
[sudo] password for user

I run the read command directly in terminal (copy and paste from script to terminal) and it works fine; it waits for an ENTER to be hit (just like a pause).

6 Answers 6

32

Because your script starts with #!/bin/sh rather than #!/bin/bash, you aren't guaranteed to have bash extensions (such as read -p) available, and can rely only on standards-compliant functionality.

See the relevant standards document for a list of functionality guaranteed to be present in read.

In this case, you'd probably want two lines, one doing the print, and the other doing the read:

printf 'press [ENTER] to continue deleting...'
read _
Sign up to request clarification or add additional context in comments.

8 Comments

I checked and my $SHELL was bash. so /bin/sh would launch bash. am I wrong?
@mohammadhmontazeri /bin/sh launches whichever shell is, well, /bin/sh -- NOT your $SHELL. Moreover, starting bash as /bin/sh (in the case where /bin/sh is a symlink to bash) disables a great deal of functionality.
@mohammadhmontazeri See mywiki.wooledge.org/BashGuide/Practices#Choose_Your_Shell for more information.
Thanks for teaching me about $REPLY as the default variable used by read @CharlesDuffy!
thanks charles, using /bin/bash corrected the script. it was mentioned in last link you sent too.
|
3

You can do this with echo command too!:

    echo "press  [ENTER]  to continue deleting line"
    read continue

2 Comments

This doesn't really solve the problem if your shell is sh because e.g. Dash does not allow you to call read without the name of a variable.
With echo (unless you have one that supports -n, which is an optional feature shells aren't required to implement), you get an extra newline this way that isn't present with the original read -p code.
3

If you use pipe to redirect contents to your function/script it will run your command in a sub-shell and set stdin (0) to a pipe, which can be checked by

$ ls -l /dev/fd/
lr-x------ 1 root root 64 May 27 14:08 0 -> pipe:[2033522138]
lrwx------ 1 root root 64 May 27 14:08 1 -> /dev/pts/11
lrwx------ 1 root root 64 May 27 14:08 2 -> /dev/pts/11
lr-x------ 1 root root 64 May 27 14:08 3 -> /proc/49806/fd

And if you called read/readarray/... command in that function/script, the read command would return immediately whatever read from that pipe as the stdin has been set to that pipe rather than the tty, which explained why read command didn't wait for input. To make read command wait for input in such case you have to restore stdin to tty by exec 0< /dev/tty before the call to read command.

Comments

2

Try this:

read -p 'press  [ENTER]  to continue deleting line' < /dev/tty

Forces the input to come from the terminal.

Tested/works using bash script on UBUNTU's GNOME terminal.

Comments

0
read -p " Ici mon texte " continue

it works on raspbian

2 Comments

Entirely unhelpful.
The answerer, and those new to this community, may find it helpful to see a more thorough reason behind a downvote.
0

Seems I'm late to the party, but echo -n "Your prompt" && sed 1q does the trick on a POSIX-compliant shell. This prints a prompt, and grabs a line from STDIN.

Alternatively, you could expand that input into a variable:

echo -n "Your prompt"
YOUR_VAR=$(sed 1q)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.