The simplest and most widely available method to get user input at a shell prompt is the read
command. The best way to illustrate its use is a simple demonstration:
while true; do
read -p "Do you wish to install this program?" yn
case $yn in
[Yy]* ) make install; break;;
[Nn]* ) exit;;
* ) echo "Please answer yes or no.";;
esac
done
Another method, pointed out by Steven Huwig, is Bash's select
command. Here is the same example using select
:
echo "Do you wish to install this program?"
select yn in "Yes" "No"; do
case $yn in
Yes ) make install; break;;
No ) exit;;
esac
done
With select
you don't need to sanitize the input – it displays the available choices, and you type a number corresponding to your choice. It also loops automatically, so there's no need for a while true
loop to retry if they give invalid input.
Also, Léa Gris demonstrated a way to make the request language agnostic in her answer. Adapting my first example to better serve multiple languages might look like this:
set -- $(locale LC_MESSAGES)
yesptrn="$1"; noptrn="$2"; yesword="$3"; noword="$4"
while true; do
read -p "Install (${yesword} / ${noword})? " yn
if [[ "$yn" =~ $yesexpr ]]; then make install; exit; fi
if [[ "$yn" =~ $noexpr ]]; then exit; fi
echo "Answer ${yesword} / ${noword}."
done
Obviously other communication strings remain untranslated here (Install, Answer) which would need to be addressed in a more fully completed translation, but even a partial translation would be helpful in many cases.
Finally, please check out the excellent answer by F. Hauri.
If you really want to just use sed -i
the 'easy' way, the following DOES work on both GNU and BSD/Mac sed
:
sed -i.bak 's/foo/bar/' filename
Note the lack of space and the dot.
Proof:
# GNU sed
% sed --version | head -1
GNU sed version 4.2.1
% echo 'foo' > file
% sed -i.bak 's/foo/bar/' ./file
% ls
file file.bak
% cat ./file
bar
# BSD sed
% sed --version 2>&1 | head -1
sed: illegal option -- -
% echo 'foo' > file
% sed -i.bak 's/foo/bar/' ./file
% ls
file file.bak
% cat ./file
bar
Obviously you could then just delete the .bak
files.
Best Solution
I've always found the BSD's to be more intuitive. There are some different philosophies in BSD than in Linux. For example, Linux prefers GNU commands, while BSD opts for either classic BSD commands (which are similar, but often times have different options) or newly written ones, falling back to GNU when nothing else is available. Also, I find the BSD Man pages to be more comprehensive and contain more examples than GNU man pages, since GNU tends to prefer info pages (which I despise) for examples.
Many ISP sysadmins swear by BSD. They claim it holds up better under load, hasn't made as many compromsies for the desktop, and that it's networking stack is more efficient and less buggy. I don't know if those are, or are still true, but this is what i've been told.
Also, OpenBSD has a reputation of focusing heavily on security, and they have historically had a very good track record when it comes to security. They take proactive measures (developing new C Runtime library routines, for instance) to prevent security flaws before they can be written.
NetBSD has a reputation of running on just about anything. They have a long list of platforms they actively support. Linux, to some extent tries to do this as well, but typically only a small subset of these are mainline supported.
Finally, it often just comes down to personal preference. Do the guys you have or are going to hire know BSD? Do you personally like it?
There are also some reasons NOT to run BSD. If you're primarily a desktop user, BSD may not be the best choice. Sure, you can install most of the same stuff on BSD as Linux, but you won't find a "distro" similar to, say, Ubuntu which focuses strictly on the desktop. Also, some device drivers aren't available on BSD because they were written with GPL only licenses.