Skip to main content
added 576 characters in body
Source Link
John1024
  • 76.4k
  • 12
  • 176
  • 165

"I want users to not have to spell out path parts when there exist variables for it (for example, $HOME for the home directory)."

That can be done without eval:

$ s='$HOME/.config'
$ s="${s//\$HOME/$HOME}"
$ echo "$s"
/home/john1024/.config

This has some limitations. For one, if both HOMES and HOME are names of variables that you want to substitute, then, to avoid false matches, HOMES must be substituted before HOME.

Applying substitutions for all exported variables

Using bash:

while IFS== read -r name val
do
   s="${s//\$$name/$val}"
done < <(printenv)

For example:

$ export A=alpha; export B=beta
$ s='$HOME/$A/$B'
$ while IFS== read -r name val; do s="${s//\$$name/$val}"; done < <(printenv)
$ echo "$s"
/home/john1024/alpha/beta

Because this approach doesn't sort the variable names by length, it has the variable overlap issue mentioned above.

We can fix that by sorting the variable names according to length:

while IFS== read -r n name val
do
   s="${s//\$$name/$val}"
done < <(printenv | awk '/^[^ \t]/{key=$0; sub(/=.*/,"",key); printf "%s=%s\n",length(key),$0}' | sort -rnt=)

Limitation: If the user enters a variable name that does not exist but the initial characters match some shorter name, the shorter name will be substituted. If this matters, we can avoid it by requiring the user to use brace-notation for this variables with this code:

while IFS== read -r n name val
do
   s="${s//\$\{$name\}/$val}"
done < <(printenv | awk '/^[^ \t]/{key=$0; sub(/=.*/,"",key); printf "%s=%s\n",length(key),$0}' | sort -rnt=)

As an example:

$ s='${HOME}/${A}/${B}'
$ while IFS== read -r n name val; do s="${s//\$\{$name\}/$val}"; done < <(printenv | awk '/^[^ \t]/{key=$0; sub(/=.*/,"",key); printf "%s=%s\n",length(key),$0}' | sort -rnt=)
$ echo "$s"
/home/john1024/alpha/beta

"I want users to not have to spell out path parts when there exist variables for it (for example, $HOME for the home directory)."

That can be done without eval:

$ s='$HOME/.config'
$ s="${s//\$HOME/$HOME}"
$ echo "$s"
/home/john1024/.config

This has some limitations. For one, if both HOMES and HOME are names of variables that you want to substitute, then, to avoid false matches, HOMES must be substituted before HOME.

Applying substitutions for all exported variables

Using bash:

while IFS== read -r name val
do
   s="${s//\$$name/$val}"
done < <(printenv)

For example:

$ export A=alpha; export B=beta
$ s='$HOME/$A/$B'
$ while IFS== read -r name val; do s="${s//\$$name/$val}"; done < <(printenv)
$ echo "$s"
/home/john1024/alpha/beta

Because this approach doesn't sort the variable names by length, it has the variable overlap issue mentioned above.

We can fix that by sorting the variable names according to length:

while IFS== read -r n name val
do
   s="${s//\$$name/$val}"
done < <(printenv | awk '/^[^ \t]/{key=$0; sub(/=.*/,"",key); printf "%s=%s\n",length(key),$0}' | sort -rnt=)

Limitation: If the user enters a variable name that does not exist but the initial characters match some shorter name, the shorter name will be substituted.

"I want users to not have to spell out path parts when there exist variables for it (for example, $HOME for the home directory)."

That can be done without eval:

$ s='$HOME/.config'
$ s="${s//\$HOME/$HOME}"
$ echo "$s"
/home/john1024/.config

This has some limitations. For one, if both HOMES and HOME are names of variables that you want to substitute, then, to avoid false matches, HOMES must be substituted before HOME.

Applying substitutions for all exported variables

Using bash:

while IFS== read -r name val
do
   s="${s//\$$name/$val}"
done < <(printenv)

For example:

$ export A=alpha; export B=beta
$ s='$HOME/$A/$B'
$ while IFS== read -r name val; do s="${s//\$$name/$val}"; done < <(printenv)
$ echo "$s"
/home/john1024/alpha/beta

Because this approach doesn't sort the variable names by length, it has the variable overlap issue mentioned above.

We can fix that by sorting the variable names according to length:

while IFS== read -r n name val
do
   s="${s//\$$name/$val}"
done < <(printenv | awk '/^[^ \t]/{key=$0; sub(/=.*/,"",key); printf "%s=%s\n",length(key),$0}' | sort -rnt=)

If the user enters a variable name that does not exist but the initial characters match some shorter name, the shorter name will be substituted. If this matters, we can avoid it by requiring the user to use brace-notation for this variables with this code:

while IFS== read -r n name val
do
   s="${s//\$\{$name\}/$val}"
done < <(printenv | awk '/^[^ \t]/{key=$0; sub(/=.*/,"",key); printf "%s=%s\n",length(key),$0}' | sort -rnt=)

As an example:

$ s='${HOME}/${A}/${B}'
$ while IFS== read -r n name val; do s="${s//\$\{$name\}/$val}"; done < <(printenv | awk '/^[^ \t]/{key=$0; sub(/=.*/,"",key); printf "%s=%s\n",length(key),$0}' | sort -rnt=)
$ echo "$s"
/home/john1024/alpha/beta
added 412 characters in body
Source Link
John1024
  • 76.4k
  • 12
  • 176
  • 165

"I want users to not have to spell out path parts when there exist variables for it (for example, $HOME for the home directory)."

That can be done without eval:

$ s='$HOME/.config'
$ s="${s//\$HOME/$HOME}"
$ echo "$s"
/home/john1024/.config

This has some limitations. For one, if both HOMES and HOME are names of variables that you want to substitute, then, to avoid false matches, HOMES must be substituted before HOME.

Applying substitutions for all exported variables

Using bash:

while IFS== read -r name val
do
   s="${s//\$$name/$val}"
done < <(printenv)

For example:

$ export A=alpha; export B=beta
$ s='$HOME/$A/$B'
$ while IFS== read -r name val; do s="${s//\$$name/$val}"; done < <(printenv)
$ echo "$s"
/home/john1024/alpha/beta

Limitation: Because this approach doesn't sort the variable names by length, it has the variable overlap issue mentioned above.

We can fix that by sorting the variable names according to length:

while IFS== read -r n name val
do
   s="${s//\$$name/$val}"
done < <(printenv | awk '/^[^ \t]/{key=$0; sub(/=.*/,"",key); printf "%s=%s\n",length(key),$0}' | sort -rnt=)

Limitation: If the user enters a variable name that does not exist but the initial characters match some shorter name, the shorter name will be substituted.

"I want users to not have to spell out path parts when there exist variables for it (for example, $HOME for the home directory)."

That can be done without eval:

$ s='$HOME/.config'
$ s="${s//\$HOME/$HOME}"
$ echo "$s"
/home/john1024/.config

This has some limitations. For one, if both HOMES and HOME are names of variables that you want to substitute, then, to avoid false matches, HOMES must be substituted before HOME.

Applying substitutions for all exported variables

Using bash:

while IFS== read -r name val
do
   s="${s//\$$name/$val}"
done < <(printenv)

For example:

$ export A=alpha; export B=beta
$ s='$HOME/$A/$B'
$ while IFS== read -r name val; do s="${s//\$$name/$val}"; done < <(printenv)
$ echo "$s"
/home/john1024/alpha/beta

Limitation: Because this approach doesn't sort the variable names by length, it has the variable overlap issue mentioned above.

"I want users to not have to spell out path parts when there exist variables for it (for example, $HOME for the home directory)."

That can be done without eval:

$ s='$HOME/.config'
$ s="${s//\$HOME/$HOME}"
$ echo "$s"
/home/john1024/.config

This has some limitations. For one, if both HOMES and HOME are names of variables that you want to substitute, then, to avoid false matches, HOMES must be substituted before HOME.

Applying substitutions for all exported variables

Using bash:

while IFS== read -r name val
do
   s="${s//\$$name/$val}"
done < <(printenv)

For example:

$ export A=alpha; export B=beta
$ s='$HOME/$A/$B'
$ while IFS== read -r name val; do s="${s//\$$name/$val}"; done < <(printenv)
$ echo "$s"
/home/john1024/alpha/beta

Because this approach doesn't sort the variable names by length, it has the variable overlap issue mentioned above.

We can fix that by sorting the variable names according to length:

while IFS== read -r n name val
do
   s="${s//\$$name/$val}"
done < <(printenv | awk '/^[^ \t]/{key=$0; sub(/=.*/,"",key); printf "%s=%s\n",length(key),$0}' | sort -rnt=)

Limitation: If the user enters a variable name that does not exist but the initial characters match some shorter name, the shorter name will be substituted.

added 382 characters in body
Source Link
John1024
  • 76.4k
  • 12
  • 176
  • 165

"I want users to not have to spell out path parts when there exist variables for it (for example, $HOME for the home directory)."

That can be done without eval:

$ s='$HOME/.config'
$ s="${s//\$HOME/$HOME}"
$ echo "$s"
/home/john1024/.config

This has some limitations. For one, if both HOMES and HOME are names of variables that you want to substitute, then, to avoid false matches, HOMES must be substituted before HOME.

Applying substitutions for all exported variables

Using bash:

while IFS== read -r name val
do
   s="${s//\$$name/$val}"
done < <(printenv)

For example:

$ export A=alpha; export B=beta
$ s='$HOME/$A/$B'
$ while IFS== read -r name val; do s="${s//\$$name/$val}"; done < <(printenv)
$ echo "$s"
/home/john1024/alpha/beta

Limitation: Because this approach doesn't sort the variable names by length, it has the variable overlap issue mentioned above.

"I want users to not have to spell out path parts when there exist variables for it (for example, $HOME for the home directory)."

That can be done without eval:

$ s='$HOME/.config'
$ s="${s//\$HOME/$HOME}"
$ echo "$s"
/home/john1024/.config

This has some limitations. For one, if both HOMES and HOME are names of variables that you want to substitute, then, to avoid false matches, HOMES must be substituted before HOME.

"I want users to not have to spell out path parts when there exist variables for it (for example, $HOME for the home directory)."

That can be done without eval:

$ s='$HOME/.config'
$ s="${s//\$HOME/$HOME}"
$ echo "$s"
/home/john1024/.config

This has some limitations. For one, if both HOMES and HOME are names of variables that you want to substitute, then, to avoid false matches, HOMES must be substituted before HOME.

Applying substitutions for all exported variables

Using bash:

while IFS== read -r name val
do
   s="${s//\$$name/$val}"
done < <(printenv)

For example:

$ export A=alpha; export B=beta
$ s='$HOME/$A/$B'
$ while IFS== read -r name val; do s="${s//\$$name/$val}"; done < <(printenv)
$ echo "$s"
/home/john1024/alpha/beta

Limitation: Because this approach doesn't sort the variable names by length, it has the variable overlap issue mentioned above.

Source Link
John1024
  • 76.4k
  • 12
  • 176
  • 165
Loading