+5  A: 

You are missing a do after the second while. (The 'B' case; compare that against the 'A' case above it.)

I use gvim which will syntax highlight shell scripts, but I think you need to ask about editors as a separate question.


As for your modified question: Your logic is broken in both the A and B cases: you need to pull the backup logic out of your if/while nesting... the if isn't actually doing anything for you. Also, be sure to quote all your filenames so that spaces don't break your script. Escape your nested quotes. I believe you need a -e on the echo statements that use \c.

So do something more like:

b|B) echo -e "Specify the ordinary file for backup and hit <Enter>: \c"
    read file
    while [ ! -f "$file" ]
    do 
        echo "Usage: \"$file\" must be an ordinary file."
        echo -e "Specify the ordinary file for backup and hit <Enter>: \c"
        read file
        if [ "$file" = "q" -o "$file" = "Q" ]
        then
            exit 0
        fi
    done
    cp "$file" "$file.bkup"
    ;;

You'll need to do the same kind of change for the A case.

retracile
Thanks for the help retracile. And I'll have to give gvim a try.
에이바
Answer updated for your new question.
retracile
I wasn't aware of the `\c` working with `echo -e` in Bash. I always do `echo -n`.
Dennis Williamson
Yeah, I generally use `-n` as well. The `-e` though lets the various `\something`s work as expected.
retracile
Yeah, I am familiar with `-e` otherwise.
Dennis Williamson
+3  A: 

Two problems in the A) directory listing section.

  1. The -o conjunction doesn't work like you think it does. Should be:

                if [ "$directory" = "q" -o "$directory" = "Q" ]
    
  2. Your outer "if" needs an "else" to handle the case when the directory given really is a directory right off the bat.

The B) backup section has the same two problems. Fix those, and both command options will work.

shoover
+2  A: 

You've quoted the $file variable in most places, but in the cp command you don't. It should be:

cp "$file" "$file.bkup"

Some of your echo commands have "\c" at the end. I think that's specific to csh. Bash will just echo the characters "\" and "c" literally.

Your statement while $TRUE works by virtue of the variable being null or unset. If it gets set to some value, it will try to execute the contents as a command. If you want to do that type of infinite loop, it's typically done in Bash like this:

while true

where true is a shell builtin. Or:

while :

where the colon is a no-op that returns true. Of course there are other ways to accomplish the same thing.

In the l|L) case you probably want to do either:

ls

or

ls $PWD

the way you have it now, it's going to try to list the entry for a file named "pwd".

Both vim and nano can do syntax highlighting for Bash. If they are not already set up in ~/.nanorc and ~/.vimrc you can do these:

for nano:

nano -Y sh scriptname

For vim:

:syntax on
:set filetype=sh
Dennis Williamson
Good catches on the `while $TRUE` and the `ls pwd`; I missed those in my answer.
retracile
The \c is not csh. Some of the old (pre-POSIX) shells used a trailing \c to suppress newlines, and the obsolete X/Open standard includes it. Try it on a Solaris box, using /usr/xpg4/bin/sh: echo "hello\c".
Idelic
+1  A: 

1) you don't to use so many echoes.. to create a menu system, you can use cat here-document,eg

cat <<EOF
-------------------------------------------------------
Select one of the following options:
d or D) Display today's date and time
l or L) List the contents of the present working directory
w or W) See who is logged in
p or P) Print the present working directory
a or A) List the contents of a specified directory
b or B) Create a backup copy of an ordinary file
q or Q) Quit this program
--------------------------------------------------------
EOF

or even this will do

echo "-------------------------------------------------------
Select one of the following options:
d or D) Display today's date and time
l or L) List the contents of the present working directory
w or W) See who is logged in
p or P) Print the present working directory
a or A) List the contents of a specified directory
b or B) Create a backup copy of an ordinary file
q or Q) Quit this program
--------------------------------------------------------"

2) when asking use to choose an option, you can use read with -p, eg

read -p "Enter your option and hit <Enter>: " choice

3) printf is more portable than echo, therefore you should use it whenever possible.

I fixed all of the echo statements as per your directions. This is my error now: ./myDemo ./myDemo: 6: Syntax error: ")" unexpected (expecting "done")
에이바