0

I have a syntax of command as

command 'variable'

The variable has to be passed in single quotes.

Now when i am using a for loop with input file as

variable1
variable2
variable3

for i in `cat $1`
do
       command '$i'
done

shell>file.sh input

The single quote is not intact as bash is not taking input as variable Please suggest how to keep the variable intact with single quotes

3
  • please do formating your codes by selecting codes and thrn press Ctrl+k Commented Apr 30, 2018 at 10:00
  • Which single quotes are we discussing? The back quotes same as $(command) or the apostrophe 'hello'? Commented Apr 30, 2018 at 11:35
  • @ctrl-alt-delor please don't change the OP's example code. It's not great, for sure, but it's what they're using. Suggest better alternatives either in an answer or as a comment. Commented Apr 30, 2018 at 11:45

4 Answers 4

3

Anything that is enclosed in single quotes will be passed exactly as you type it. So command '$i' will pass a string consisting of the two characters $ and i to the command.

You should use double quotes to get the variable's value used instead

for i in `cat $1`
do
       command "$i"
done

Or, since your code expects a single word per line in your file, replace the entire loop with this single line:

xargs -n1 -r command <"$1"
4
  • Thanks for your input Roajma but the variable has to be in single quotes else it will fail.
    – Vishal
    Commented Apr 30, 2018 at 11:41
  • @Vishal if you put the variable in single quotes its name (and the leading $) will be treated as a literal string. If you're getting failures with my suggested code it would help tremendously to see an example of the data in your source file. Commented Apr 30, 2018 at 11:42
  • Hereis a SAP command for index rebuild: brspace -c force -p initPRD.sap -s 20 -l E -u / -f idrebuild -i 'index_name' [Index_name has to be in single quotes if we simply use " " in bash it will be come as] brspace -c force -p initPRD.sap -s 20 -l E -u / -f idrebuild -i index_name [which will fail my index rebuild command as index_name had single quotes missing]
    – Vishal
    Commented Apr 30, 2018 at 11:50
  • 1
    @Vishal I have no idea what that's supposed to say. Please edit your question to show your new information. Commented Apr 30, 2018 at 12:52
1

This might do as requested:

while read i
do
       command "'$i'"
done < "$1"
1

If you want to call command for each line of a file (whose path is stored in $1), with the content of the line passed verbatim as one single argument to command, then you'd use:

  • With GNU xargs:

    xargs -d '\n' -n 1 -r -a "$1" command
    
  • With POSIX shells:

    while IFS= read -r line <&3; do
      command "$line" 3<&-
    done 3< "$1"
    

Your

for i in `cat $1`; do
  command '$i'
done

beside the obvious problem that it passes a literal $i string to command has several other problems:

  • You forgot to quote $1, which means it is subject to split+glob which means it wouldn't work properly for file paths that contains spaces, tabs, newlines or wildcard characters
  • You forgot the -- to mark the end of options to cat which means it wouldn't work properly for file paths that start with -. Even with cat -- "$1", it wouldn't work for a file called -. cat < "$1" would be better. Note that if your command also accepts options, you may also need to use -- there (xargs ... command -- or command -- "$line")
  • That `cat $1` invokes the split+glob operator again. So it's not looping over the lines of the file but over the list of files that match each of the glob patterns that result of the splitting of the content of the file.
1
  • Reviewing that while loop, the purpose of using <3, (instead of just <), is not obvious.
    – agc
    Commented Nov 25, 2018 at 22:24
0

You could use the command, without quotes:

for i in `cat $1`
do
       command $i
done

With single quote '$i': you get literally $i.

With double quote "$i": you get the values in $i, but as a single string (which is usually the desired behaviour).

Without quotes $i: this will expand as the value in $i, but than the arguments are split. So, if you have a space, e.g. -a -b, with double quote you have an argument -a -b which is not normally expected, but in the last case, you will have -a and -b as two different arguments.

I should advise you, that not using quotes is often a security issue, so you should do that only if you really know that inputs is not malicious.

3
  • Hereis a SAP command for index rebuild: brspace -c force -p initPRD.sap -s 20 -l E -u / -f idrebuild -i 'index_name' [Index_name has to be in single quotes if we simply use " " in bash it will be come as] brspace -c force -p initPRD.sap -s 20 -l E -u / -f idrebuild -i index_name [which will fail my index rebuild command as index_name had single quotes missing] In short, my SAP commands needs value passed in single quotes. Please help to achieve that as i need to automate certain tasks
    – Vishal
    Commented Apr 30, 2018 at 12:20
  • Sorry I do not understand. Please edit your question and add that sentence, reformatted and in a less concise way. Is the above command the command in your question? Where is $i? We can solve only problems that are in the question. Commented Apr 30, 2018 at 12:27
  • Why index_name should be in single quote? Shell will remove quote in any case. Of index_name is a string with spaces? Commented Apr 30, 2018 at 13:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .