Can ${var} parameter expansion expressions be nest

2019-01-01 07:17发布

What I have is this:

progname=${0%.*}
progname=${progname##*/}

Can this be nested (or not) into one line, i.e. a single expression?

I'm trying to strip the path and extension off of a script name so that only the base name is left. The above two lines work fine. My 'C' nature is simply driving me to obfuscate these even more.

标签: bash
13条回答
何处买醉
2楼-- · 2019-01-01 07:52

I know this is an ancient thread, but here are my 2 cents.

Here's an (admittedly kludgy) bash function which allows for the required functionality:

read_var() {
  set | grep ^$1\\b | sed s/^$1=//
}

Here's a short test script:

#!/bin/bash

read_var() {
  set | grep ^$1\\b | sed s/^$1=//
}

FOO=12
BAR=34

ABC_VAR=FOO
DEF_VAR=BAR

for a in ABC DEF; do
  echo $a = $(read_var $(read_var ${a}_VAR))
done

The output is, as expected:

ABC = 12
DEF = 34
查看更多
公子世无双
3楼-- · 2019-01-01 07:54

This nesting does not appear to be possible in bash, but it works in zsh:

progname=${${0%.*}##*/}
查看更多
无与为乐者.
4楼-- · 2019-01-01 07:55

eval will allow you to do what you are wanting:

export HELLO="HELLO"
export HELLOWORLD="Hello, world!"

eval echo "\${${HELLO}WORLD}"

Output: Hello, world

查看更多
忆尘夕之涩
5楼-- · 2019-01-01 07:56

Expressions like ${${a}} do not work. To work around it, you can use eval:

b=value
a=b
eval aval=\$$a
echo $aval

Output is

value

查看更多
无色无味的生活
6楼-- · 2019-01-01 07:58

If by nest, you mean something like this:

#!/bin/bash

export HELLO="HELLO"
export HELLOWORLD="Hello, world!"

echo ${${HELLO}WORLD}

Then no, you can't nest ${var} expressions. The bash syntax expander won't understand it.

However, if I understand your problem right, you might look at using the basename command - it strips the path from a given filename, and if given the extension, will strip that also. For example, running basename /some/path/to/script.sh .sh will return script.

查看更多
后来的你喜欢了谁
7楼-- · 2019-01-01 08:04

Actually it is possible to create nested variables in bash, using two steps.

Here is a test script based upon the post by Tim, using the idea suggested by user1956358.

#!/bin/bash
export HELLO="HELLO"
export HELLOWORLD="Hello, world!"

# This command does not work properly in bash
echo ${${HELLO}WORLD}

# However, a two-step process does work
export TEMP=${HELLO}WORLD
echo ${!TEMP}

The output is:

Hello, world!

There are lots of neat tricks explained by running 'info bash' from the command line, then searching for 'Shell Parameter Expansion'. I've been reading a few myself today, just lost about 20 minutes of my day, but my scripts are going to get a lot better...

Update: After more reading I suggest this alternative per your initial question.

progname=${0##*/}

It returns

bash
查看更多
登录 后发表回答