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.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a script with the following variable assignment:


What does the ${3#?} do?

share|improve this question

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:


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##*,}

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"

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
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 '14 at 16:17
@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 '14 at 16:23
@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 '14 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 '14 at 0:08
@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 '14 at 20:02

Your Answer


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.