PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Forums Hébergement > Forum Serveur - Sécurité et techniques > comp.unix.shell > Dealing with File Arguments and Spaces
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
comp.unix.shell Using and programming the Unix shell.

Dealing with File Arguments and Spaces

Réponse
 
LinkBack Outils de la discussion
Vieux 16/07/2007, 03h30   #1
mfuhrer
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Dealing with File Arguments and Spaces

I am attempting to write a wrapper shell script that invokes a program
along with file arguments. For example, I could invoke a text editor
with two file arguments by running my script as follows:

> ./wrapper1.sh file.txt 'file 2.txt'


Two important requirements are that:
1) I can pass as many file arguments as I wish, and
2) the file names can include spaces.

A simple, effective solution is the following script.

-----------
wrapper1.sh
-----------
#!/bin/sh -x

PROGRAM=xemacs
$PROGRAM "$@"


In addition to file arguments, I would also like to pass flags to my
wrapper script, eg:

> ./wrapper2.sh -flag file.txt 'file 2.txt'


I attempted to modify my script as follows:

-----------
wrapper2.sh
-----------
#!/bin/sh -x

PROGRAM=xemacs
files=
flags=

for arg
do
case "$arg" in
-*) flags="$arg $flags" ;;
*) files="$arg $files" ;;
esac
done

$PROGRAM "$files"


The script now places all flag arguments in the "flags" variable
(which I will use for further processing in my final script), and all
file arguments in the "files" variable. Alas, running the script with
the two file arguments file.txt and 'file 2.txt' as shown earlier
results in xemacs being launched with a single file argument named
"file 2.txt file.txt". If I modify the last line in wrapper2.sh as
follows:

$PROGRAM $files

xemacs is launched with three file arguments: "file", "2.txt", and
"file.txt".

How can I modify wrapper2.sh so that it properly passes file arguments
to the program?

  Réponse avec citation
Vieux 16/07/2007, 04h32   #2
Chris F.A. Johnson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Dealing with File Arguments and Spaces

On 2007-07-16, mfuhrer wrote:
> I am attempting to write a wrapper shell script that invokes a program
> along with file arguments. For example, I could invoke a text editor
> with two file arguments by running my script as follows:
>
>> ./wrapper1.sh file.txt 'file 2.txt'

>
> Two important requirements are that:
> 1) I can pass as many file arguments as I wish, and
> 2) the file names can include spaces.
>
> A simple, effective solution is the following script.
>
> -----------
> wrapper1.sh
> -----------
> #!/bin/sh -x
>
> PROGRAM=xemacs
> $PROGRAM "$@"
>
>
> In addition to file arguments, I would also like to pass flags to my
> wrapper script, eg:
>
>> ./wrapper2.sh -flag file.txt 'file 2.txt'

>
> I attempted to modify my script as follows:
>
> -----------
> wrapper2.sh
> -----------
> #!/bin/sh -x
>
> PROGRAM=xemacs
> files=
> flags=
>
> for arg
> do
> case "$arg" in
> -*) flags="$arg $flags" ;;
> *) files="$arg $files" ;;
> esac
> done
>
> $PROGRAM "$files"
>
>
> The script now places all flag arguments in the "flags" variable
> (which I will use for further processing in my final script), and all
> file arguments in the "files" variable. Alas, running the script with
> the two file arguments file.txt and 'file 2.txt' as shown earlier
> results in xemacs being launched with a single file argument named
> "file 2.txt file.txt". If I modify the last line in wrapper2.sh as
> follows:
>
> $PROGRAM $files
>
> xemacs is launched with three file arguments: "file", "2.txt", and
> "file.txt".
>
> How can I modify wrapper2.sh so that it properly passes file arguments
> to the program?


Use single letters for the options and use getopts to process them:

optstring=a:b ## list options here; colon follows those that take args

while getopts "$optstring" opt
do
case opt in
a) a_flag=1 ;;
b) b_val=$OPTARG ;;
*) echo "Invalid option: $opt" >&2; exit 1 ;;
esac
done
shift "$(( $OPTIND - 1 ))"

## The remaining arguments contain the file names


If you really want long options, use something like this:

opts=
for x in "$@"
do
case $1 in
-*) opts="$opts $1"; shift ;;
*) break ;;
esac
done


If you want to allow the options to be intermingled with the
filenames:

opts=
for x in "$@"
do
case $1 in
-*) opts="$opts $1"; shift ;;
*) file=$1
shift
set -- "$@" "$file"
;;
esac
done


--
Chris F.A. Johnson, author <http://cfaj.freeshell.org/shell/>
Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
===== My code in this post, if any, assumes the POSIX locale
===== and is released under the GNU General Public Licence
  Réponse avec citation
Vieux 16/07/2007, 05h54   #3
Icarus Sparry
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Dealing with File Arguments and Spaces

On Sun, 15 Jul 2007 23:32:46 -0400, Chris F.A. Johnson wrote:

> On 2007-07-16, mfuhrer wrote:
>> I am attempting to write a wrapper shell script that invokes a program
>> along with file arguments. For example, I could invoke a text editor
>> with two file arguments by running my script as follows:
>>
>>> ./wrapper1.sh file.txt 'file 2.txt'

>>
>> Two important requirements are that:
>> 1) I can pass as many file arguments as I wish, and 2) the file names
>> can include spaces.
>>
>> A simple, effective solution is the following script.
>>
>> -----------
>> wrapper1.sh
>> -----------
>> #!/bin/sh -x
>>
>> PROGRAM=xemacs
>> $PROGRAM "$@"
>>
>>
>> In addition to file arguments, I would also like to pass flags to my
>> wrapper script, eg:
>>
>>> ./wrapper2.sh -flag file.txt 'file 2.txt'

>>
>> I attempted to modify my script as follows:
>>
>> -----------
>> wrapper2.sh
>> -----------
>> #!/bin/sh -x
>>
>> PROGRAM=xemacs
>> files=
>> flags=
>>
>> for arg
>> do
>> case "$arg" in
>> -*) flags="$arg $flags" ;;
>> *) files="$arg $files" ;;
>> esac
>> done
>>
>> $PROGRAM "$files"
>>
>>
>> The script now places all flag arguments in the "flags" variable (which
>> I will use for further processing in my final script), and all file
>> arguments in the "files" variable. Alas, running the script with the
>> two file arguments file.txt and 'file 2.txt' as shown earlier results
>> in xemacs being launched with a single file argument named "file 2.txt
>> file.txt". If I modify the last line in wrapper2.sh as follows:
>>
>> $PROGRAM $files
>>
>> xemacs is launched with three file arguments: "file", "2.txt", and
>> "file.txt".
>>
>> How can I modify wrapper2.sh so that it properly passes file arguments
>> to the program?

>
> Use single letters for the options and use getopts to process them:
>
> optstring=a:b ## list options here; colon follows those that take args
>
> while getopts "$optstring" opt
> do
> case opt in
> a) a_flag=1 ;;
> b) b_val=$OPTARG ;;
> *) echo "Invalid option: $opt" >&2; exit 1 ;;
> esac
> done
> shift "$(( $OPTIND - 1 ))"
>
> ## The remaining arguments contain the file names
>
>
> If you really want long options, use something like this:
>
> opts=
> for x in "$@"
> do
> case $1 in
> -*) opts="$opts $1"; shift ;;
> *) break ;;
> esac
> done
>
>
> If you want to allow the options to be intermingled with the
> filenames:
>
> opts=
> for x in "$@"
> do
> case $1 in
> -*) opts="$opts $1"; shift ;;
> *) file=$1
> shift
> set -- "$@" "$file"
> ;;
> esac
> done


This advice comes down to "use an array to hold your filenames, rather
than a string". The original Bourne shell effectively only had a single
array, the one referenced by "$@". Modern POSIX shells have as many
arrays as you want. If your flags can have spaces in them, then you
should accumulate them in a second array.
  Réponse avec citation
Vieux 16/07/2007, 06h22   #4
Chris F.A. Johnson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Dealing with File Arguments and Spaces

On 2007-07-16, Icarus Sparry wrote:
....
> This advice comes down to "use an array to hold your filenames, rather
> than a string". The original Bourne shell effectively only had a single
> array, the one referenced by "$@". Modern POSIX shells have as many
> arrays as you want.


POSIX shells have no more arrays than the Bourne shell.

Bash and ksh have integer arrays; ksh93 also has associative
arrays.

--
Chris F.A. Johnson, author <http://cfaj.freeshell.org/shell/>
Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
===== My code in this post, if any, assumes the POSIX locale
===== and is released under the GNU General Public Licence
  Réponse avec citation
Vieux 16/07/2007, 06h52   #5
mfuhrer
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Dealing with File Arguments and Spaces

On Jul 15, 10:54 pm, Icarus Sparry <use...@icarus.freeuk.com> wrote:
> This advice comes down to "use an array to hold your filenames, rather
> than a string". The original Bourne shell effectively only had a single
> array, the one referenced by "$@". Modern POSIX shells have as many
> arrays as you want. If your flags can have spaces in them, then you
> should accumulate them in a second array.


Interesting, I never realized $@ was an array. In the past I was
puzzled why something like

files="$@"
xemacs "$files"

never produced the same result as

xemacs "$@"

Given the array explanation, I now realize that the correct solution
is:

files=("$@")
$PROGRAM "${files[@]}"

It all starts to gel. Thanks!

Martin





  Réponse avec citation
Vieux 16/07/2007, 06h55   #6
mfuhrer
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Dealing with File Arguments and Spaces

On Jul 15, 9:32 pm, "Chris F.A. Johnson" <cfajohn...@gmail.com> wrote:
> If you want to allow the options to be intermingled with the
> filenames:
>
> opts=
> for x in "$@"
> do
> case $1 in
> -*) opts="$opts $1"; shift ;;
> *) file=$1
> shift
> set -- "$@" "$file"
> ;;
> esac
> done


Chris - thanks for your thorough reply! These are exactly the
solutions I was looking for; the last one is particularly useful for
what I want to accomplish. Thanks again,

Martin


  Réponse avec citation
Vieux 16/07/2007, 12h29   #7
Chris F.A. Johnson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Dealing with File Arguments and Spaces

On 2007-07-16, mfuhrer wrote:
> On Jul 15, 10:54 pm, Icarus Sparry <use...@icarus.freeuk.com> wrote:
>> This advice comes down to "use an array to hold your filenames, rather
>> than a string". The original Bourne shell effectively only had a single
>> array, the one referenced by "$@". Modern POSIX shells have as many
>> arrays as you want. If your flags can have spaces in them, then you
>> should accumulate them in a second array.

>
> Interesting, I never realized $@ was an array.


It's not, but "$@" is. The quotes are important,

> In the past I was
> puzzled why something like
>
> files="$@"
> xemacs "$files"
>
> never produced the same result as
>
> xemacs "$@"
>
> Given the array explanation, I now realize that the correct solution
> is:
>
> files=("$@")
> $PROGRAM "${files[@]}"


That is not part of the POSIX standard; in a simple instance like
that, use (in *any* Bourne-type shell):

$PROGRAM "$@"

--
Chris F.A. Johnson, author <http://cfaj.freeshell.org/shell/>
Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
===== My code in this post, if any, assumes the POSIX locale
===== and is released under the GNU General Public Licence
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 07h57.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,15089 seconds with 15 queries