0

On Linux Ubuntu, when you do sudo apt update && sudo apt install perl, it adds the following to the bottom of your ~/.bashrc file (at least, many months later, I think that is what added those lines):

PATH="/home/gabriel/perl5/bin${PATH:+:${PATH}}"; export PATH;
PERL5LIB="/home/gabriel/perl5/lib/perl5${PERL5LIB:+:${PERL5LIB}}"; export PERL5LIB;
PERL_LOCAL_LIB_ROOT="/home/gabriel/perl5${PERL_LOCAL_LIB_ROOT:+:${PERL_LOCAL_LIB_ROOT}}"; export PERL_LOCAL_LIB_ROOT;
PERL_MB_OPT="--install_base \"/home/gabriel/perl5\""; export PERL_MB_OPT;
PERL_MM_OPT="INSTALL_BASE=/home/gabriel/perl5"; export PERL_MM_OPT;

What does this strange syntax do in many of the lines, including in the first line? It appears to be some sort of bash array slicing:

${PATH:+:${PATH}}

The ${PATH} part is pretty straightforward: it reads the contents of the PATH variable, but the rest is pretty cryptic to me.

Cyrus
  • 84,225
  • 14
  • 89
  • 153
Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265

2 Answers2

2

It's not array slicing; it's a use of one of the POSIX parameter expansion operators. From the bash man page, in the Parameter Expansions section,

${parameter:+word}

Use Alternate Value. If parameter is null or unset, nothing is substituted, otherwise the expansion of word is substituted.

It's a complex way of making sure that you only add a : to the value if PATH isn't empty to start with. A longer, clearer way of writing it would be

if [ -n "$PATH" ]; then
    PATH=/home/gabriel/perl5/bin:$PATH
else
    PATH=/home/gabriel/perl5/bin
fi        

However, since it if almost inconceivable that PATH is empty when .basrhc is sourced, it would be simpler to just prepend the new path and be done with it.

PATH=/home/gabriel/perl5/bin:$PATH

If PATH actually ended with a :, it would implicitly include the current working directory in the search path, which isn't a good idea for security reasons. Also from the bash man page, in the section on Shell Variables under the entry for PATH:

A zero-length (null) directory name in the value of PATH indicates the current directory. A null directory name may appear as two adjacent colons, or as an initial or trailing colon.


As an aside, it's good to understand what various installers try to add to your shell configuration. It's not always necessary, and sometimes can actively change something you already have configure.

I would much prefer if packages simply printed instructions for what needs to be added to your configuration (and why), and leave it to the user to make the appropriate modifications.

Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
chepner
  • 497,756
  • 71
  • 530
  • 681
  • Bash is one of my primary languages. I use it even more than Python, yet it never ceases to amaze me just how much _bash is nuts._ :) It is definitely one of the less-readable languages out there. – Gabriel Staples Jan 08 '22 at 21:13
  • 1
    It all stems from the fact that its basic job (run a program with arguments) requires *no* syntax aside from spaces to separate each word. That means virtually everything else requires some additional syntax to avoid confusion with executing a simple command. – chepner Jan 08 '22 at 21:16
  • 1
    (And over the years, more and more functionality has been shoehorned into a language that wasn't designed for it.) – chepner Jan 08 '22 at 21:20
1
What does this strange syntax do in many of the lines, including in the first line?

It's the ${parameter:+word} form of parameter expansion where word becomes the expanded value if parameter is not unset and not having the value of an empty string (a.k.a. null).

konsolebox
  • 72,135
  • 12
  • 99
  • 105