简体   繁体   中英

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.)

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 .

Try running it with bash.

bash test.sh helloworld.zip

-likewise-

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

Try that in bash :

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

Adapt it to fit your needs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM