Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a script with the following variable assignment:

TEST_VARIABLE=${3#?}

What does the ${3#?} do?

share|improve this question

2 Answers 2

That is called parameter expansion:

  1. $3 is your variable, which is the third parameter of the script/function.
  2. # will remove the shortest prefix of the variable.
  3. ? is the pattern you are looking for (in this case is any character).

So basically you remove the shortest prefix of the variable named 3 until you find the pattern.

In general, we can consider:

${variable_name[option][pattern]}

There are other options like:

  • ## remove largest prefix.
  • % remove shortest suffix.
  • %% remove largest suffix.

Which you can combine with other patterns, for example, for getting the last field of a CSV line:

> string="asdf,1234,aa,foo22"
> echo ${string##*,}
foo22

Notice how we have removed the largest prefix searching for the pattern "any character(s) followed by a comma".

share|improve this answer
> set -- 1 2 foo
> echo "$3"
foo
TEST_VARIABLE=${3#?}
> echo "$TEST_VARIABLE"
oo

It assigns the value of the third positional parameter without its first char to the variable TEST_VARIABLE (the positional parameter itself is not changed); used in functions or shell scripts:

./myscript 1 2 foo
# or
myfunc 1 2 foo
  # within each $3 is foo

In order to have positional parameters within an interactive shell you need set.

share|improve this answer
1  
Why do you write "usually used in functions"? I'm at a loss to understand why you'd want to drop the first character of an argument. –  Bruce Ediger May 28 at 16:17
1  
@BruceEdiger That was bad wording indeed. I meant "You don't have that in interactive shells" but, of course, it's pretty normal in scripts, too. And I have no idea either why someone should use this code. –  Hauke Laging May 28 at 16:23
2  
@BruceEdiger - could be just a sloppy means of removing a leading -dash? Still, it's impossible to judge without the code. By the way, though, it doesn't actually drop the first character of the positional parameter - it expands without it. So set -- one two three ; echo "${3#?}" "$3" gets you hree and three. You don't lose anything - it's still there. You'd have to set -- to clear the args. –  mikeserv May 28 at 23:50
    
@BruceEdiger - I wrote this other answer today about argument mangling and it reminded me of your comment about dropping a character from an argument. I do at least that several times over in this little function and I feel it's justified. Am I crazy? unix.stackexchange.com/a/132447/52934 –  mikeserv May 31 at 0:08
1  
@mikeserv - your code doesn't look crazy to me. If you need to remove the first character of a variable's value, that's one way of doing it. The "${3#?}" usage seems to hide what it's doing, rather than make it explicit. –  Bruce Ediger May 31 at 20:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.