Bash scripting and user input
Looking for some nudging to help me write a bash script.
I'm browsing the bash tutorials, but am coming up short with additional examples that will help me. I want to do the following: Code:
if [ ! -z $PS1 ] ; then How do I parse the response (similar to BASIC Left(String,1) command)? Additionally, the script will unmount /mnt partitions using umount /mnt/*. I would like the script to terminate gracefully, with an error message to the screen, if the umount command fails while trying to unmount any partition. I'm not asking for a full fledged script, just some help or nudging in the correct direction or some links that will help me learn. I am the only one running this script. Therefore I "know" what responses will work properly, but I'd like to use this exercise to improve my knowledge of bash and write a more [strikethrough]idiot-proof[/strikethrough] robust script. TIA! P.S. Is there no strikethrough bbcode at this board like at other boards? |
How do I ignore case
Say you want to match responses y, yes and yeah, you could grep case-insensitive: echo "$response"|grep -qie "y[a-z]\{0,3\}" && do_cmd or convert case: case "$(echo "$response"|tr "[A-Z]" "[a-z]")" in y|yes|yeah) do_cmd;; *) exit 1;; esac How do I parse the response See "man test"?, BTW write this: if [ $response != y ] && [ $response != Y ] && [ $response != yes ] && [ $response != YES ] ; then as: if [ $response != y -o $response != Y -o $response != yes -o $response != YES ] ; then , but convert to lower + "case" should be easier here. I would like the script to terminate gracefully, with an error message to the screen, if the umount command fails while trying to unmount any partition. You're looking for the exit status of a command (echo "$?"), but using "umount /mnt/*" isn't gonna work right if you want to show the status for all devices, besides you don't want to exit if it fails on the first umount? # Since everything is mounted through /proc we'll take input from there. # This way we avoid globbing symlinks and don't umount stuff that isn't mounted. grep "^/dev/[h,s]d" /proc/mounts | while read garbage part; do echo -en "Umounting ${part}: "; umount "$part" 2>&1>/dev/null; case "$?" in 0) r=OK;; *) r=FAILED;; esac; echo $r done If you OTOH would only want to be shown errors on exit: parts=""; grep "^/dev/[h,s]d" /proc/mounts | while read no part; do umount "$part" 2>&1>/dev/null; case "$?" in 0) ;; *) parts="$parts $part";; esac done; echo "These partitions failed to umount properly: ${parts}" improve my knowledge of bash and write a more idiot-proof robust script. That starts IMHO by not trusing sanitising user input. Here's a stupid example that only allows some chars to be used: # Read-only variable declare -r allowedchars="/._-1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" expr index "$response" "${allowedchars}" >/dev/null || ( echo "Input contains illegal chars, exiting."; exit 1 ) P.S. Is there no strikethrough bbcode at this board like at other boards? No. Use a felt tip pen :-] |
Re: Bash scripting and user input
Quote:
Like this: Code:
if [ ${response:0:1} != y -o ${response:0:1} != Y ]; then ........ |
Not sure if this will help or not but the last time i wanted to do something depending on user input i used the case statement (i suppose it is similar to a previous example).
Code:
read ANSWER Cheers |
Wow. Way too much for my puny brain. :) Actually, there is some good info here that I want to sift and use.
For example, I like the idea of limiting user input. From the above example, if I want to limit input to n/N/y/Y do I merely delete all of the characters except those four? That is, would I type: allowedchars="nyNY" Additionally, if one of those four characters is not entered, how do I loop back to my originating question, rather than exiting the script? Yeah, I know, I did not ask or infer that in my original post. :) Parsing the first character of the response: ${response:0:1}. That looks slick. With that tip I eventually found the convention mentioned in the Advanced Bash Scripting guide. Cool! :) My original question is backup related. Thus, I want to still test if my umount command works (using /proc/mount as described above), but I also want to still query the user (me) if I am sure I want to continue. Grep is still A Strange Thing to me, but I'll use the examples provided to hopefully go further. Regarding the ability to return the exit status of a command, the above example used echo "$?" as part of a case-esac procedure. After some quick surfing I think I can conclude that this command is a special 'nix variable? I'm trying to learn more about this because I have another script where I need to know this information. Question: I notice that many people often end their scripts with exit 0. Is this A Good Thing or common practice? I notice PV does this in most or all of his rc.d scripts. What is the reasoning behind this practice? |
You could try this:
Code:
allowedchars="YyNn" Then you can evaluate the response and act upon it. Eric |
Quote:
- zero equals success - nonzero equals failure Hope that helps. |
Quote:
Quote:
|
Quote:
Several scripts are being "sourced" in Slackware's init scripts (i.e. run like ". somescript" which can also be written as "source somescript"). The "." or "source" command is a shell internal command. Sourcing a script means that the script is executed in the current shell instead of spawning another shell to run the script's commands. Now, if the sourced script calls "exit", your parent script will exit too, right there! Try this: Copy this into a shell script, call it test1.sh and make it executable: Code:
#!/bin/sh Code:
#!/bin/sh Code:
./test1.sh Eric |
Quote:
In a much related question to this scripting business, thanks to the previous information, I know how to parse text from a variable. But how do I assign text to a variable extracted through grep? I've been searching for an hour or so for this, but to no avail. :( Maybe the answer in obvious to all casual observers but me. What I want is: VARIABLE=(grep -i "text to find" "file to search") Additionally, how do I calculate the string length of a variable? LENGTH=(count the number of characters in VARIABLE) I imagine some kind of For-Do loop, but the syntax of all of this bashing is still new to me. If this info is covered in one of the primary bash guides, then just point me to the appropriate sections of those guides. Thanks again! |
Like this:
Code:
VARIABLE=`grep -i "text to find" "file to search"` Code:
${#VARIABLE} |
Quote:
Quote:
|
By the way, a must-have for your bookmarks is this URL: the Advanced Bash-Scripting Guide
Cheers, Eric |
Quote:
Quote:
But I'm stuck on stinking dialup. Therefore I downloaded both the HTML and PDF versions so I can browse more conveniently. I've provided technical writing services for two decades and I learned long ago that even the best of documentation is useless if one does not form the question that suits the style of the documentation. I think most of the answers provided in this thread, and in a few others I've posted recently, actually are documented in the three bash guides, but to a beginning basher who does not yet know the language and syntax of bash I was unable to find my solution in the guides until after all of you provided the necessary hints. And I'm grateful for that! Yes, I could sit and actually read the entire guide, all of them, but as I'm sure many will agree, reading is not the same as doing. Actually writing a script paints one into a corner that necessitates asking specific questions, and that process far outpaces trying to read and sponge an entire document into memory! I do not consider myself a noob at computers (been using them for more than two decades) or Slackware (been using for a year), but the entire 'nix environment is far too complex for anybody to master fully. For that reason alone, I'm grateful for all of you expert Slackers here at LQ. Thank you! Oh, and FWIW, I now have some nice bash scripts thanks to all of the bite-size hints and answers provided in these threads. Again thank you all! I only hope as time progresses that I too can provide some meaningful help to other people. |
All times are GMT -5. The time now is 06:32 AM. |