Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash tilde *substring* expansion - undocumented feature?

Tags:

bash

I was surprised that this expansion:

$ echo "${foo:~abc}"

yielded the empty string when foo was unset. I expected that it would parse like this:

$ echo "${foo:(~abc)}"

and yield the string "~abc". But instead, I found that if I did define

$ foo='abcdefg'
$ echo "${foo:~abc}"
g

In fact, it's taking "abc" in arithmetic context and doing. "${foo:~0}". Likewise

$ foo='abcdefg'
$ echo "${foo:~3}"
defg

It gets you the last n+1 characters of the expansion. I looked in the "Parameter Expansion" section of the manpage. I see no mention of tildes there. Bash Hackers Wiki only mentions tildes as (also undocumented) case modifiers.

This behavior goes back to at least 3.2.57.

Am I just missing where this form of substring expansion is documented, or is it not documented at all?

like image 855
kojiro Avatar asked Jul 29 '15 14:07

kojiro


People also ask

What does the tilde do in Bash?

Bash also performs tilde expansion on words satisfying the conditions of variable assignments (see Shell Parameters) when they appear as arguments to simple commands. Bash does not do this, except for the declaration commands listed above, when in POSIX mode.

What is tilde expansion?

Tilde expansion is the process of converting these abbreviations to the directory names that they stand for. Tilde expansion applies to the ' ~ ' plus all following characters up to whitespace or a slash.

What is tilde in shell script?

The tilde (~) is a Linux "shortcut" to denote a user's home directory. Thus tilde slash (~/) is the beginning of a path to a file or directory below the user's home directory. For example, for user01, file /home/user01/test.

What is Bash $@?

bash [filename] runs the commands saved in a file. $@ refers to all of a shell script's command-line arguments. $1 , $2 , etc., refer to the first command-line argument, the second command-line argument, etc. Place variables in quotes if the values might have spaces in them.


1 Answers

It's not undocumented (you may have been confusing ${foo:~abc} with ${foo-~abc}).

${parameter:offset}
${parameter:offset:length}
     Substring Expansion.  Expands to up to length characters of  the
     value  of  parameter starting at the character specified by off-
     set.  [...]  If length is omitted, expands to the  substring  of  the
     value of parameter starting at the character specified by offset
     and extending to the end of the value.  length  and  offset  are
     arithmetic expressions (see ARITHMETIC EVALUATION below).

Here, ~abc is the offset field of the expansion, and ~ is the bitwise negation operator in the arithmetic expression. An undefined parameter evaluates to 0 in an arithmetic expression, and ~0 == -1.

like image 181
chepner Avatar answered Oct 04 '22 08:10

chepner