Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

shell string bad substitution

I'm new to shell programming. I intend to get directory name after zip file was extracted. The print statement of it is

$test.sh helloworld.zip
helloworld

Let's take a look at test.sh:

#! /bin/sh
length=echo `expr index "$1" .zip`
a=$1    
echo $(a:0:length}

However I got the Bad substitution error from the compiler.

And when I mention about 'shell'.I just talking about shell for I don't know the difference between bash or the others.I just using Ubuntu 10.04 and using the terminal. (I am using bash.)

like image 647
cattail Avatar asked Oct 11 '12 03:10

cattail


People also ask

What is bad substitution in shell script?

Bad Substitution Error Related to Command Substitution One circumstance in which this error occurs is when you want to use command substitution but by mistake you use curly braces instead of parentheses. Command substitution allows to store the output of a Bash command (as complex as you want) into a variable.

What is shell substitution?

Command substitution is the mechanism by which the shell performs a given set of commands and then substitutes their output in the place of the commands.

What does ${} mean in shell?

Here are all the ways in which variables are substituted in Shell: ${variable} This command substitutes the value of the variable. ${variable:-word} If a variable is null or if it is not set, word is substituted for variable.

What is $? == 0 in shell script?

$? is the exit status of the most recently-executed command; by convention, 0 means success and anything else indicates failure. That line is testing whether the grep command succeeded. The grep manpage states: The exit status is 0 if selected lines are found, and 1 if not found.


3 Answers

Try running it with bash.

bash test.sh helloworld.zip

-likewise-

"try changing the first line to #!/bin/bash" as comment-answered by – @shellter

like image 30
Brian Davis Avatar answered Oct 01 '22 18:10

Brian Davis


If your shell is a sufficiently recent version of bash, that parameter expansion notation should work.

In many other shells, it will not work, and a bad substitution error is the way the shell says 'You asked for a parameter substitution but it does not make sense to me'.


Also, given the script:

#! /bin/sh
length=echo `expr index "$1" .zip`
a=$1    
echo $(a:0:length}

The second line exports variable length with value echo for the command that is generated by running expr index "$1" .zip. It does not assign to length. That should be just:

length=$(expr index "${1:?}" .zip)

where the ${1:?} notation generates an error if $1 is not set (if the script is invoked with no arguments).

The last line should be:

echo ${a:0:$length}

Note that if $1 holds filename.zip, the output of expr index $1 .zip is 2, because the letter i appears at index 2 in filename.zip. If the intention is to get the base name of the file without the .zip extension, then the classic way to do it is:

base=$(basename $1 .zip)

and the more modern way is:

base=${1%.zip}

There is a difference; if the name is /path/to/filename.zip, the classic output is filename and the modern one is /path/to/filename. You can get the classic output with:

base=${1%.zip}
base=${base##*/}

Or, in the classic version, you can get the path with:

base=$(dirname $1)/$(basename $1 .zip)`.)

If the file names can contain spaces, you need to think about using double quotes, especially in the invocations of basename and dirname.

like image 186
Jonathan Leffler Avatar answered Oct 01 '22 19:10

Jonathan Leffler


Try that in bash :

echo $1
len=$(wc -c <<< "$1")
a="${1}.zip"
echo ${a:0:$len}

Adapt it to fit your needs.

like image 43
Gilles Quenot Avatar answered Oct 01 '22 18:10

Gilles Quenot