LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Bash script - repeated command (https://www.linuxquestions.org/questions/programming-9/bash-script-repeated-command-246954/)

satimis 10-24-2004 11:34 PM

Bash script - repeated command
 
Hi folks,

I have a script which needs following command to repeat confirmation on questions.

Code:

......
read -p "Add Document directory <yes/no>"
if [ "$REPLY" = "yes" ]; then
  cp -r /home/satimis/Document/* /home/satimis/Temp/dir1/
else
  cancel
fi

read -p "Add Photo directory <yes/no>"
if [ "$REPLY" = "yes" ]; then

  cp -r /home/satimis/Photo/* /home/satimis/Temp/dir2/
else
  cancel
fi
.....

If for 10+ confirmations there will be a long script. Kindly advise how to avoid it.

TIA

B.R.
satimis

gizmo_thunder 10-25-2004 12:20 AM

y dont' you just use the while loop??

nitin_batta 10-25-2004 01:26 AM

Just make a seperate file having the questions and then use the script as

Code:

for i in `cat q_file`
do
read -p "$i <yes/no>"
if [ "$REPLY" = "yes" ]; then
  cp -r /home/satimis/Document/* /home/satimis/Temp/dir1/
else
  cancel
fi

q_file is the file containing all the question u ask i the script.

micxz 10-25-2004 02:02 AM

But "cp -r /home/satimis/Document/*" does not suggest the folder name. Thus only copies the "Document/" contents only everytime. So it is not fuctional for what satimis is trying to do.

How about:

Code:

for i in `cat q_file`
do
read -p "Whould you like $i <yes/no>? "
        if [ "$REPLY" = "yes" ]; then
        cp -r /home/satimis/$i/* /home/satimis/Temp/dir1/
        fi
done

This assuming "q_file" looks like:
Photo
Documents
New_Folder
Whatever

Also I think you want:

cp -r /home/satimis/$i/ /home/satimis/Temp/dir1/

Because you want to copie the whole directory and not just the files within right?

jlliagre 10-25-2004 02:18 AM

But micxz is missing the dir1, dir2, ... requirement, what about:
Code:

i=0
for dir in Document Photo etcetera
do
  read -p "Add $dir directory <yes/no> "
  if [ "$REPLY" = "yes" ]; then
    i=$((i+1))
    cp -r /home/satimis/$dir/* /home/satimis/Temp/dir$i/
  else
    break # not sure of that one, what was the initial "cancel" for ?
  fi
done


nitin_batta 10-25-2004 02:25 AM

Quote:

This assuming "q_file" looks like:
Photo
Documents
New_Folder
Whatever

Also I think you want:

cp -r /home/satimis/$i/ /home/satimis/Temp/dir1/

Because you want to copie the whole directory and not just the files within right
Point taken i just missed on that.:D

micxz 10-25-2004 02:31 AM

Quote:

Originally posted by jlliagre But micxz is missing the dir1, dir2, ... requirement
for i in `cat q_file`

is the same as

for i in Document Photo.....

In this example, so how am I missing dir1 and dir2...

jlliagre 10-25-2004 02:41 AM

If you look closely to the requirements, each copy is going to a different directory:
Document is going to dir1
Photo is going to dir2,
your solution is copying all to dir1, so doesn't comply.

By the way:

Code:

cp -r /home/satimis/$i/ /home/satimis/Temp/dir1/
is doing the very same operation that
Code:

/home/satimis/$i /home/satimis/Temp/dir1/
assuming $i is a directory, I dont see a point here.

micxz 10-25-2004 02:50 AM

Yep your right and I see now about this being pointless. Maybe it was meant to be:

cp -r /home/satimis/$i/ /home/satimis/Temp/

Then maybe there is a point.

jlliagre 10-25-2004 03:09 AM

Nope, the same.

The only difference in using a trailing slash is that if $i is a file, an error is triggered and the file is not copied, while with no slash, whether it is a file or a directory doesn't matter, it is copied to the destination directory.

For the first remark, I was not arguing of using a separate file for the directory list, which can be a good idea, especially if the file itself need to created by another program, but about the extra level of directories necessary to avoid same name files to be overwritten.

satimis 10-25-2004 03:57 AM

Hi folks,

Lot of thanks for your suggestions. Hereinunder is the complete script
Code:

!/bin/bash

# Set ISO filename...
user=$(whoami)
now=$(date +%Y.%m.%d.%R)
ISO_File="/home/satimis/To_burn/image_${user}_${now}.iso"
dir1=/Document/=/home/satimis/Temp/dir1/
dir2=/Photo/=/home/satimis/Temp/dir2/

read -p "Add Document directory <yes/no>"
if [ "$REPLY" = "yes" ]; then
  cp -r /home/satimis/Document/* /home/satimis/Temp/dir1/
else
  cancel
fi

read -p "Add Photo directory <yes/no>"
if [ "$REPLY" = "yes" ]; then
  cp -r /home/satimis/Photo/* /home/satimis/Temp/dir2/
else
  cancel
fi

# Loop to get directories...
echo "Enter directories to burn.  Leave blank to end list"
entry="empty"
list=""
until [ -z $entry ]; do
  echo -n "Enter a directory: "
  read entry
  if [ $entry != "" ]; then
    list="$list $1$entry"
  fi
done

# Create ISO file...
mkisofs -R -l -graft-points -hide-rr-moved \
$dir1 \
$dir2 \
$list |\
cdrecord dev=ATA:1,0,0 -v -eject -

# Delete directories and files...
rm -r /home/satimis/Temp/dir1/* /home/satimis/Temp/dir2/*

dir1, dir2…. etc. are only transit directories. The files copied to there will be removed finally after the running of the whole script.

Actually this is not a good arrangement. But I’m not allowed to touch the “cdrecord” command
Code:

# Create ISO file...
mkisofs -R -l -graft-points -hide-rr-moved \
$dir1 \
$dir2 \
$list |\
cdrecord dev=ATA:1,0,0 -v -eject –

I need a further confirmation before adding dir1, dir2, dir3…. etc. each to the ISO file.

Have any other suggestions? TIA

B.R.
satimis

jlliagre 10-25-2004 05:59 AM

Some comments:

you call the cancel command if the user is not willing to add Document of Photo directories. This command's purpose is to cancel a printing job in progress, I'm quite sure it's not what you meant.

Why didn't you take or comment any of our suggestions about optimisation ?

You last loop isn't testing the validity of the directory entered.

/bin/bash 10-25-2004 11:40 AM

#!/bin/bash
# Set ISO filename...
user=$(whoami)
now=$(date +%Y.%m.%d.%R)
ISO_File="/home/satimis/To_burn/image_${user}_${now}.iso"
dir1=/Document/=/home/satimis/Temp/dir1/
dir2=/Photo/=/home/satimis/Temp/dir2/


# This starts my modifications. Note this is untested!
cp_documents() {
cp -r /home/satimis/Document/* /home/satimis/Temp/dir1/
}

cp_pictures() {
cp -r /home/satimis/Pictures/* /home/satimis/Temp/dir1/
}

REPLY="B"
until [ $REPLY = "" ]
do
echo "Choose one of the following:"
echo
echo "[D]ocuments"
echo "[P]ictures"
echo "[B]oth"
echo
echo "[Enter] = Exit"
echo

read

case "$REPLY" in

"D" | "d" )
# Accept upper or lowercase input.
cp_documents
;;

"P" | "p" )
cp_pictures
;;

"B" | "b" )
cp_documents
cp_pictures
;;

* )
# Default option.
# Do nothing for other keys
;;

esac
done


# The rest of the script is yours
# Create ISO file...
mkisofs -R -l -graft-points -hide-rr-moved \
$dir1 \
$dir2 \
$list |\
cdrecord dev=ATA:1,0,0 -v -eject -

satimis 10-25-2004 10:41 PM

Hi /bin/bash,

Tks for your advice.

Testing result is as follows;

Script
Code:

#!/bin/bash

# Set ISO filename...
user=$(whoami)
now=$(date +%Y.%m.%d.%R)
ISO_File="/home/satimis/To_burn/image_${user}_${now}.iso"
dir1=/Document/=/home/satimis/Temp/dir1/
dir2=/Photo/=/home/satimis/Temp/dir2/

# This starts my modifications. Note this is untested!
cp_documents() {
cp -r /home/satimis/Document/* /home/satimis/Temp/dir1/
}

cp_pictures() {
cp -r /home/satimis/Photo/* /home/satimis/Temp/dir1/
}


REPLY="B"
until [ $REPLY = "" ]
do
echo "Choose one of the following:"
echo
echo "[D]ocuments"
echo "[P]ictures"
echo "[B]oth"
echo
echo "[Enter] = Exit"
echo

read

case "$REPLY" in

"D" | "d" )
# Accept upper or lowercase input.
cp_documents
;;

"P" | "p" )
cp_pictures
;;

"B" | "b" )
cp_documents
cp_pictures
;;

* )
# Default option.
# Do nothing for other keys
;;

esac
done

# Loop to get directories...
echo "Enter directories to burn.  Leave blank to end list"
entry="empty"
list=""
until [ -z $entry ]; do
  echo -n "Enter a directory: "
  read entry
  if [ $entry != "" ]; then
    list="$list $1$entry"
  fi
done

# Create ISO file...
mkisofs -R -l -o "$ISO_File" -graft-points -hide-rr-moved \
$dir1 \
$dir2 \
$list |\
cdrecord dev=ATA:1,0,0 -v -eject -

$ ./cdmaker
Code:

Choose one of the following:
[D]ocuments
[P]ictures
[B]oth

[Enter] = Exit

D

It hung here.

Remark: also tried P,p,B,b
same result

B.R.
satimis

nitin_batta 10-25-2004 11:36 PM

Quote:

REPLY="B"
until [ $REPLY = "" ]
do
echo "Choose one of the following:"
echo
echo "[D]ocuments"
echo "[P]ictures"
echo "[B]oth"
echo
echo "[Enter] = Exit"
echo

read

case "$REPLY" in

"D" | "d" )
# Accept upper or lowercase input.
cp_documents
;;

"P" | "p" )
cp_pictures
;;

"B" | "b" )
cp_documents
cp_pictures
;;
You have to user read REPLY on place of just read so that variable read is assigned a value.

Code:

echo

read REPLY

case "$REPLY" in

"D" | "d" )


satimis 10-26-2004 01:02 AM

Hi /bin/bash,

Further to my last posting. Sorry I made a mistake. Your script works. Because of the size of the directories I have to wait.

Testing result is as follows;

Script
Code:

#!/bin/bash

# Set ISO filename...
user=$(whoami)
now=$(date +%Y.%m.%d.%R)
ISO_File="/home/satimis/To_burn/image_${user}_${now}.iso"
dir1=/Document/=/home/satimis/Temp/dir1/
dir2=/Photo/=/home/satimis/Temp/dir2/

# This starts my modifications. Note this is untested!
cp_documents() {
cp -r /home/satimis/Document/* /home/satimis/Temp/dir1/
}

cp_pictures() {
cp -r /home/satimis/Photo/* /home/satimis/Temp/dir1/
}


REPLY="B"
until [ $REPLY = "" ]
do
echo "Choose one of the following:"
echo
echo "[D]ocuments"
echo "[P]ictures"
echo "[B]oth"
echo
echo "[Enter] = Exit"
echo

read

case "$REPLY" in

"D" | "d" )
# Accept upper or lowercase input.
cp_documents
;;

"P" | "p" )
cp_pictures
;;

"B" | "b" )
cp_documents
cp_pictures
;;

* )
# Default option.
# Do nothing for other keys
;;

esac
done

# Loop to get directories...
echo "Enter directories to burn.  Leave blank to end list"
entry="empty"
list=""
until [ -z $entry ]; do
  echo -n "Enter a directory: "
  read entry
  if [ $entry != "" ]; then
    list="$list $1$entry"
  fi
done

# Create ISO file...
mkisofs -R -l -o "$ISO_File" -graft-points -hide-rr-moved \
$dir1 \
$dir2 \
$list |\
cdrecord dev=ATA:1,0,0 -v -eject -

$ ./cdmaker
Code:

Choose one of the following:
[D]ocuments
[P]ictures
[B]oth

[Enter] = Exit

D

D/d/P/p
worked copying files to dir1/dir2 respectively but can't create ISO file. After hitting >ENTER>
Code:

./cdmaker: line 21: [: =: unary operator expected
Choose one of the following:

[D]ocuments
[P]ictures
[B]oth

[Enter] = Exit

B/b
all files copied to dir1 from [D]ocuments and [P]ictures directories

B.R.
satimis

jlliagre 10-26-2004 02:36 AM

Code:

cp -r /home/satimis/Photo/* /home/satimis/Temp/dir1/
should be
Code:

cp -r /home/satimis/Photo/* /home/satimis/Temp/dir2/
and
Code:

  if [ $entry != "" ]; then
    list="$list $1$entry"
  fi

could be improved in
Code:

  if [ $entry != "" ]; then
    if [ -d "$1$entry" ]; then
        list="$list $1$entry"
    else
        echo $1$entry: no such directory
    fi
  fi


satimis 10-26-2004 03:32 AM

Hi jlliagre,

Tks for your advice. Correction made.

Script
Code:

#!/bin/bash

# Set ISO filename...
#Set directory path...
user=$(whoami)
now=$(date +%Y.%m.%d.%R)
ISO_File="/home/satimis/To_burn/image_${user}_${now}.iso"
dir1=/Document/=/home/satimis/Temp/dir1/
dir2=/Photo/=/home/satimis/Temp/dir2/

# This starts my modifications. Note this is untested!
cp_fedoracore2() {
cp -r /home/satimis/Document/* /home/satimis/Temp/dir1/
}

cp_fedoracore2-photo() {
cp -r /home/satimis/Photo/* /home/satimis/Temp/dir2/
}

REPLY="B"
until [ $REPLY = "" ]

do
echo "Choose one of the following:"
echo
echo "[D]ocument"
echo "[P]hoto"
echo "[B]oth"
echo
echo "[Enter] = Exit"
echo

read

case "$REPLY" in

"D" | "d" )
# Accept upper or lowercase input.
cp_document
;;

"P" | "p" )
cp_photo
;;

"B" | "b" )
cp_document
cp_photo
;;

* )
#Default option.
# Do nothing for other keys
;;

esac
done

# Loop to get directories...
echo "Enter directories to burn.  Leave blank to end list"
entry="empty"
list=""
until [ -z $entry ]; do
  echo -n "Enter a directory: "
  read entry
  if [ $entry != "" ]; then
    list="$list $1$entry"
  else
    echo $1$entry: no such directory
  fi
fi

# Create ISO file...
mkisofs -R -l -o "$ISO_File" -graft-points -hide-rr-moved \
$dir1 \
$dir2 \
$list
#cdrecord dev=ATA:1,0,0 -v -eject -

# Delete directories and files...
#rm -r /home/satimis/Temp/dir1/* /home/satimis/Temp/dir2/*

$ ./cdmaker
Choose one of the following:

[D]ocument
[P]hoto
[B]oth

[Enter] = Exit

f
Choose one of the following:

[D]ocument
[P]hoto
[B]oth

[Enter] = Exit

p
Choose one of the following:

[D]ocument
[P]hoto
[B]oth

[Enter] = Exit

It hung here after hitting <ENTER>. Files copied to dir1 and dir2 respectively but can't create ISO file.

B.R.
satimis

jlliagre 10-26-2004 04:16 AM

Code:

echo "Enter directories to burn.  Leave blank to end list"
entry="empty"
list=""
until [ -z $entry ]; do
  echo -n "Enter a directory: "
  read entry
  if [ $entry != "" ]; then
    list="$list $1$entry"
  else
    echo $1$entry: no such directory
  fi
fi

should be
Code:

echo "Enter directories to burn.  Leave blank to end list"
entry="empty"
list=""
until [ -z "$entry" ]; do
  echo -n "Enter a directory: "
  read entry
  if [ -d  "$entry" ]; then
    list="$list $1$entry"
  else
    echo $1$entry: no such directory
  fi
done


/bin/bash 10-26-2004 10:46 AM

Quote:

You have to user read REPLY on place of just read so that variable read is assigned a value.
Actually REPLY is the default variable used with read if no other variable is supplied.

The problem is with the until test. It needs to be changed like this.
until [ $REPLY = "" ]
s/b
until [ z$REPLY = "z" ]

Sorry about that. But I did say it was untested.

satimis 10-26-2004 11:56 AM

Hi /bin/bash,

Quote:

s/b
until [ z$REPLY = "z" ]

Tks for your advice. The script is now running without problem.

Could you please help me to understand the function of "z"

TIA

B.R.
satimis

jlliagre 10-26-2004 12:48 PM

The ugly way to handle empty strings:
Quote:

until [ z$REPLY = "z" ]
a better way to do it:
Quote:

until [ "$REPLY" = "" ]
and the right way:
Quote:

until [ -z "$REPLY" ]
Does anyone reads my previous postings,I already gave a working solution ...:confused:

satimis 10-26-2004 07:57 PM

Quote:

Originally posted by jlliagre
The ugly way to handle empty strings:

a better way to do it:

and the right way:

Does anyone reads my previous postings,I already gave a working solution ...:confused:

Hi jlliagre,

Both suggestions of yours worked for me here.

I don't understand the function of "z", could you please explain it.

TIA

B.R.
satimis

Tinkster 10-26-2004 08:02 PM

Try reading, mate :) Has always worked miracles for me ;}


http://www.tldp.org/LDP/abs/html/testconstructs.html

Cheers,
Tink

jlliagre 10-26-2004 08:11 PM

The z is prefixing the variable, so if the variable is empty, the test if [ z = "z" ] is true.
Without the z on both sides, the test would become if [ = "" ] which is a syntax error.

Any character or string can be used instead of z, but anyway, this is a very poor programming technique, as the variable can be put between double quotes to avoid the shell complaining.

satimis 10-27-2004 03:56 AM

Quote:

Originally posted by jlliagre
The z is prefixing the variable, so if the variable is empty, the test if [ z = "z" ] is true.
Without the z on both sides, the test would become if [ = "" ] which is a syntax error.

Any character or string can be used instead of z, but anyway, this is a very poor programming technique, as the variable can be put between double quotes to avoid the shell complaining.

Hi jlliagre,

Noted with thanks

B.R.
satimis

satimis 10-27-2004 03:59 AM

Quote:

Originally posted by Tinkster
Try reading, mate :) Has always worked miracles for me ;}

http://www.tldp.org/LDP/abs/html/testconstructs.html

Hi Tinkster,

Tks for your link.

Sorry, I did not catch "Try reading, mate Has always worked miracles for me"

B.R.
satimis

/bin/bash 10-28-2004 05:02 AM

The nice thing about helping people for free is that no one expects you to sit down and write perfect code, using only "good programming technique." Well usually thats true. :rolleyes:

Anyways satimis, if you are ever in a hurry, you don't have time for debugging and you forget what the test is for empty string, you at least know how to do it the UGLY way. ;)


All times are GMT -5. The time now is 09:26 AM.