bash, command line substitution


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting bash, command line substitution
# 1  
Old 09-14-2011
bash, command line substitution

I have one script calling another with a set of strings that includes white space. Script A calls Script B with these input strings: one two "th ree"

Script B pulls apart the arguments correctly:
arg0 = one, arg1 = two, arg2 = "th ree"

if I call it from within Script A like so:
Code:
../scriptB.sh  one two "th ree"

However I'd like to have the list of arguments contained within a variable. e.g. my_args = one two "th ree" and then call it like:
Code:
../scriptB.sh  $my_args

But whenever I try to put that list in a variable the args wind up as:
arg0 = one, arg1 = two, arg2 = "th, arg3 = ree"

Tried many combinations. Is there some kind of limitation regarding "$@"?

Here is script B (shamelessly plagiarized from the net):

Code:
#!/bin/bash 
echo "------------------------------"
echo allargs: "$@"

# build array from input $@ to ensure multi-word 
# elements can include whitespace

i=0
for arg in "$@"
do
	argArray[$i]=$arg
	let "i+=1"
done

elem_cnt=${#argArray[@]}
echo elem count: $elem_cnt

indx=0

# print array contents
while [ "$indx" -lt "$elem_cnt" ]
do
	echo "arg[$indx]: ${argArray[indx]}"
	let indx+=1
done

exit 0

Now I'm sure there are many ways to successfully script the functionality I described, but I'm mainly interested in understanding this problem. Is what I'm attempting impossible? And if so why?.
# 2  
Old 09-15-2011
You could try
Code:
$ my_args="one,two,th ree"
$ OIFS=$IFS
$ IFS=,
$ ../scriptB.sh  $my_args
$ IFS=$OIFS

# 3  
Old 09-15-2011
Quote:
Originally Posted by skippyV
Is what I'm attempting impossible? And if so why?.
The magic combination is "$@". It's special because most things in quotes don't split at all, but "$@" does split -- but only on arguments, never on IFS.

You can feed this into a BASH array easily.
Code:
ARR=( "$@" )

This will put all the arguments into an array one at a time without splitting on anything at all.

If this doesn't work, it's not your script that's splitting them, but something earlier.
# 4  
Old 09-15-2011
Data

Once again I've somehow failed to clarify the gist of my question. Apologies, and thanks for responding.
Script B, which splits the arguments as desired, is not the problem. It uses "$@" but just loops over the args to give us a verification.
It's formatting of the input that has my stymied.
So let's assume we don't alter Script B. And Script A receives input that it has to pass onto Script B.
If we echo the input from within Script A it looks like:
one two "th ree"
If we take the above line and paste it "as is" into the call to Script B:
Code:
/home/scriptB.sh  one  two  "th ree"

then the args get separated as desired.
But if we try to configure a variable with the same contents as the above string AND we want the same result:
Code:
/home/scriptB.sh $mystr

then it does not work for me.
I don't know how to format the string of the variable such that it is processed identically to the method of just manually entering the chars.
# 5  
Old 09-15-2011
Quote:
Originally Posted by skippyV
If we take the above line and paste it "as is" into the call to Script B:
Code:
/home/scriptB.sh  one  two  "th ree"

then the args get separated as desired.
But if we try to configure a variable with the same contents as the above string AND we want the same result:
Code:
/home/scriptB.sh $mystr

then it does not work for me.
Ah. I see now.

The only way to perfectly do what you want is eval, which isn't just awkward, it's dangerous:
Code:
# eval considers a string as its own shell statement, which 
# will process one two "th ree" as three strings as intended.
$ STR='one two "th ree"'
$ eval "printf \"%s\n\" $STR"
one
two
th ree

# But this means it will swallow ANY valid shell syntax, including
# backticks, variable assignments, etc, etc, etc.
# Someone could make your program do anything by feeding
# it the right string.
$ STR='one two "th ree" `touch /`'
$ eval "printf \"%s\n\" $STR"
touch: setting times of `/': Permission denied
one
two
th ree

Why not just use an array in the first place? Much simpler, much safer.
# 6  
Old 09-15-2011
Smilie Much thanks, Corona. Eval did the trick.
I can reformat the input before passing it to script B. But once the input is in a variable and passing the variable to script B - the elements get split on the space within the multi-word element. And it keeps the quotations. One element is
Quote:
"th
and the other is
Quote:
ree"
So in script B if I just set an array to the input:
Code:
myArray=("$@")

then the unwanted split occurs.
But with eval it works as desired.
Am I missing something?
I was playing with the idea of substituting the quotations for other characters, and then converting the spaces between each set of quotations to yet another character! Messy.
I understand the danger of eval but for my purpose this shouldn't be a issue.

---------- Post updated at 03:14 PM ---------- Previous update was at 02:02 PM ----------

This site helps explain the details of why eval is necessary.
HTML Code:
http://fvue.nl/wiki/Bash:_Why_use_eval_with_variable_expansion%3F

Last edited by skippyV; 09-15-2011 at 04:57 PM..
# 7  
Old 09-15-2011
I'm still not convinced you need eval, you're not using arrays correctly. If you can possibly avoid using eval, you'll be better off for it -- it's finicky and dangerous.

Quote:
Originally Posted by skippyV
So in script B if I just set an array to the input:
Code:
myArray="$@"

then the unwanted split occurs.
That's no spoon array, this is an array: myArray=( "$@" )

You can get its contents out splitting on index instead of spaces too: "${myArray[@]}"

It'd be nice if you show the half of the code that's sending your string, not just the half that's receiving it. Both need fixing; you shouldn't need to pass literal quotes into anything.

Last edited by Corona688; 09-15-2011 at 04:40 PM..
Login or Register to Ask a Question

Previous Thread | Next Thread

9 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

Question on bash command line

OS : RHEL / Oracle Linux 6.8 In bash shell, how can I replace a character under the cursor with another character ? In the below example , after I typed the following line, I realized that I meant 7013 and not 2013. So I move the cursor to the left and keep it on top of 2 (of 2013) and I want... (7 Replies)
Discussion started by: kraljic
7 Replies

2. Shell Programming and Scripting

How to run several bash commands put in bash command line?

How to run several bash commands put in bash command line without needing and requiring a script file. Because I'm actually a windows guy and new here so for illustration is sort of : $ bash "echo ${PATH} & echo have a nice day!" will do output, for example:... (4 Replies)
Discussion started by: abdulbadii
4 Replies

3. Shell Programming and Scripting

Cp command works on command line but not in bash

The below command moves all the .vcf files into the directory. cp /home/cmccabe/Desktop/test/vcf/overall/stats/*.vcf /home/cmccabe/Desktop/NGS/annovar When I use a bash wrapper the target.txt gets created but the text files do not get copied. All the paths are the same, but not sure why... (2 Replies)
Discussion started by: cmccabe
2 Replies

4. Shell Programming and Scripting

How to Force command substitution evaluation in bash?

OK, I'm striving to abide by all the rules this time. Here is a fragment of my windows10/cygwin64/bash script: export BUPLOG=$(BackupRecords --log "$src") robocopy $(BackupRecords -mrbd "$src" --path "$src") $(BackupRecords --appSwitches "$src") "$src" "$dst" $(BackupRecords --fileSwitches... (15 Replies)
Discussion started by: siegfried
15 Replies

5. Shell Programming and Scripting

How to Force command substitution evaluation in bash?

OK, I'm striving to abide by all the rules this time. Here is a fragment of my windows10/cygwin64/bash script: export BUPLOG=$(BackupRecords --log "$src") robocopy $(BackupRecords -mrbd "$src" --path "$src") $(BackupRecords --appSwitches "$src") "$src" "$dst" $(BackupRecords --fileSwitches... (0 Replies)
Discussion started by: siegfried
0 Replies

6. Shell Programming and Scripting

Bash - Loading a command's output line by line into an array

I have been trying this a lot of different ways and haven't found too much online. Here's what I've got so far: j=0 declare -a first zero=(`cat $tmpfile`) for i in "${zero}" do command $i >> "${first}" ... (4 Replies)
Discussion started by: Azrael
4 Replies

7. UNIX for Dummies Questions & Answers

Running set options from the command line and bash command

I'm reading about debugging aids in bash and have come across the set command. It says in my little book that an addition to typing set you can also use them "on the command line when running a script..." and it lists this in a small table: set -o option Command Line... (5 Replies)
Discussion started by: Straitsfan
5 Replies

8. AIX

Typing "bash" at the command line spawns two bash processes

Server: IBM p770 OS: AIX 6.1 TL5 SP1 When one of our develoeprs types "bash" on the command line to switch shells, it hangs. For some reason, two bash processes are created....the first bash process spawns a second bash process in the same console, causing a hang. Anyone have any idea what... (2 Replies)
Discussion started by: wjssj
2 Replies

9. Shell Programming and Scripting

[bash] command line substitution with environmental variables

Hi, I'm using an array that contains compiler FLAGS that need to be executed either before ./configure or after the main 'make' command. example of array containing compiler flags. ------------------------------------------------- FLAGS="CFLAGS=\"-arch x86_64 -g -Os -pipe... (7 Replies)
Discussion started by: ASGR
7 Replies
Login or Register to Ask a Question