How Can I Expand A Tilde ~ As Part Of A Variable?cp command saying directory does not exist when it doesWhy...

My previous employer committed a severe violation of the law and is also being sued by me. How do I explain the situation to future employers?

Can one block with a protection from color creature?

What does "spinning upon the shoals" mean?

Can a landlord force all residents to use the landlord's in-house debit card accounts?

How should I ask for a "pint" in countries that use metric?

QR codes, do people use them?

Users forgotting to regenerate PDF before sending it

US citizen traveling with Peruvian passport

Is it possible to complete a PhD in CS in 3 years?

Is "wissen" the only verb in German to have an irregular present tense?

How to "add vert" in blender 2.8?

What was the nature of the known bugs in the Space Shuttle software?

Passwordless authentication - how and when to invalidate a login code

What factors could lead to bishops establishing monastic armies?

Interpretation of non-significant results as "trends"

Is there a method for differentiating informative comments from commented out code?

Writing an ace/aro character?

My professor has told me he will be the corresponding author. Will it hurt my future career?

How do I explain that I don't want to maintain old projects?

Is it ok for parents to kiss and romance with each other while their 2- to 8-year-old child watches?

How do resistors generate different heat if we make the current fixed and changed the voltage and resistance? Notice the flow of charge is constant

stuck {in/at} beta

Why did Old English lose both thorn and eth?

Why am I getting unevenly-spread results when using $RANDOM?



How Can I Expand A Tilde ~ As Part Of A Variable?


cp command saying directory does not exist when it doesWhy can't execute ls or cp commands with a variable as an argumentWhy doesn't the tilde (~) expand inside double quotes?Any problem assigning one variable to another in shell without using quotes?Do I need to quote command substitutions when assigning their output to a variable?using tilde in variable from the userreading input in sedattempting to put dynamic input data in a variable via cat methodWhy can I change bash history?BASH: Using awk to filter unique lines results in 0 length arrayWhat's the correct way to pass a variable as an argument to another command?Create new array with unique values from existing arrayCan't pipe from echo to bash built-in read?Set comparator with variables within a variable, then have shell expand those variables each time it's echo'dShell Script: how to expand a variable into quotesBash terminal trying to read a previously installed file on each start up






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







7















When I open up a bash prompt and type:



$ set -o xtrace
$ x='~/someDirectory'
+ x='~/someDirectory'
$ echo $x
+ echo '~/someDirectory'
~/someDirectory


I was hoping that the 5th line above would have went + echo /home/myUsername/someDirectory. Is there a way to do this? In my original Bash script, the variable x is actually being populated from data from an input file, via a loop like this:



while IFS= read line
do
params=($line)
echo ${params[0]}
done <"./someInputFile.txt"


Still, I'm getting a similar result, with the echo '~/someDirectory' instead of echo /home/myUsername/someDirectory.










share|improve this question























  • In ZSH this is x='~'; print -l ${x} ${~x}. I gave up after digging through the bash manual for a while.

    – thrig
    Oct 20 '17 at 19:02











  • @thrig: This is not a bashism, this behavior is POSIX.

    – WhiteWinterWolf
    Oct 20 '17 at 21:35











  • Extremely closely related (if not a dupe): unix.stackexchange.com/questions/151850/…

    – Kusalananda
    Oct 20 '17 at 21:42











  • @Kusalananda: I'm not sure this is a dupe as the reason here is somewhat different: the OP did not enclose $x between quotes when echoing it.

    – WhiteWinterWolf
    Oct 20 '17 at 21:55











  • You don't put tildes in the input file. Problem solved.

    – chepner
    Oct 21 '17 at 1:24


















7















When I open up a bash prompt and type:



$ set -o xtrace
$ x='~/someDirectory'
+ x='~/someDirectory'
$ echo $x
+ echo '~/someDirectory'
~/someDirectory


I was hoping that the 5th line above would have went + echo /home/myUsername/someDirectory. Is there a way to do this? In my original Bash script, the variable x is actually being populated from data from an input file, via a loop like this:



while IFS= read line
do
params=($line)
echo ${params[0]}
done <"./someInputFile.txt"


Still, I'm getting a similar result, with the echo '~/someDirectory' instead of echo /home/myUsername/someDirectory.










share|improve this question























  • In ZSH this is x='~'; print -l ${x} ${~x}. I gave up after digging through the bash manual for a while.

    – thrig
    Oct 20 '17 at 19:02











  • @thrig: This is not a bashism, this behavior is POSIX.

    – WhiteWinterWolf
    Oct 20 '17 at 21:35











  • Extremely closely related (if not a dupe): unix.stackexchange.com/questions/151850/…

    – Kusalananda
    Oct 20 '17 at 21:42











  • @Kusalananda: I'm not sure this is a dupe as the reason here is somewhat different: the OP did not enclose $x between quotes when echoing it.

    – WhiteWinterWolf
    Oct 20 '17 at 21:55











  • You don't put tildes in the input file. Problem solved.

    – chepner
    Oct 21 '17 at 1:24














7












7








7


1






When I open up a bash prompt and type:



$ set -o xtrace
$ x='~/someDirectory'
+ x='~/someDirectory'
$ echo $x
+ echo '~/someDirectory'
~/someDirectory


I was hoping that the 5th line above would have went + echo /home/myUsername/someDirectory. Is there a way to do this? In my original Bash script, the variable x is actually being populated from data from an input file, via a loop like this:



while IFS= read line
do
params=($line)
echo ${params[0]}
done <"./someInputFile.txt"


Still, I'm getting a similar result, with the echo '~/someDirectory' instead of echo /home/myUsername/someDirectory.










share|improve this question














When I open up a bash prompt and type:



$ set -o xtrace
$ x='~/someDirectory'
+ x='~/someDirectory'
$ echo $x
+ echo '~/someDirectory'
~/someDirectory


I was hoping that the 5th line above would have went + echo /home/myUsername/someDirectory. Is there a way to do this? In my original Bash script, the variable x is actually being populated from data from an input file, via a loop like this:



while IFS= read line
do
params=($line)
echo ${params[0]}
done <"./someInputFile.txt"


Still, I'm getting a similar result, with the echo '~/someDirectory' instead of echo /home/myUsername/someDirectory.







bash shell-script shell quoting variable






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Oct 20 '17 at 18:34









AndrewAndrew

1381 silver badge5 bronze badges




1381 silver badge5 bronze badges













  • In ZSH this is x='~'; print -l ${x} ${~x}. I gave up after digging through the bash manual for a while.

    – thrig
    Oct 20 '17 at 19:02











  • @thrig: This is not a bashism, this behavior is POSIX.

    – WhiteWinterWolf
    Oct 20 '17 at 21:35











  • Extremely closely related (if not a dupe): unix.stackexchange.com/questions/151850/…

    – Kusalananda
    Oct 20 '17 at 21:42











  • @Kusalananda: I'm not sure this is a dupe as the reason here is somewhat different: the OP did not enclose $x between quotes when echoing it.

    – WhiteWinterWolf
    Oct 20 '17 at 21:55











  • You don't put tildes in the input file. Problem solved.

    – chepner
    Oct 21 '17 at 1:24



















  • In ZSH this is x='~'; print -l ${x} ${~x}. I gave up after digging through the bash manual for a while.

    – thrig
    Oct 20 '17 at 19:02











  • @thrig: This is not a bashism, this behavior is POSIX.

    – WhiteWinterWolf
    Oct 20 '17 at 21:35











  • Extremely closely related (if not a dupe): unix.stackexchange.com/questions/151850/…

    – Kusalananda
    Oct 20 '17 at 21:42











  • @Kusalananda: I'm not sure this is a dupe as the reason here is somewhat different: the OP did not enclose $x between quotes when echoing it.

    – WhiteWinterWolf
    Oct 20 '17 at 21:55











  • You don't put tildes in the input file. Problem solved.

    – chepner
    Oct 21 '17 at 1:24

















In ZSH this is x='~'; print -l ${x} ${~x}. I gave up after digging through the bash manual for a while.

– thrig
Oct 20 '17 at 19:02





In ZSH this is x='~'; print -l ${x} ${~x}. I gave up after digging through the bash manual for a while.

– thrig
Oct 20 '17 at 19:02













@thrig: This is not a bashism, this behavior is POSIX.

– WhiteWinterWolf
Oct 20 '17 at 21:35





@thrig: This is not a bashism, this behavior is POSIX.

– WhiteWinterWolf
Oct 20 '17 at 21:35













Extremely closely related (if not a dupe): unix.stackexchange.com/questions/151850/…

– Kusalananda
Oct 20 '17 at 21:42





Extremely closely related (if not a dupe): unix.stackexchange.com/questions/151850/…

– Kusalananda
Oct 20 '17 at 21:42













@Kusalananda: I'm not sure this is a dupe as the reason here is somewhat different: the OP did not enclose $x between quotes when echoing it.

– WhiteWinterWolf
Oct 20 '17 at 21:55





@Kusalananda: I'm not sure this is a dupe as the reason here is somewhat different: the OP did not enclose $x between quotes when echoing it.

– WhiteWinterWolf
Oct 20 '17 at 21:55













You don't put tildes in the input file. Problem solved.

– chepner
Oct 21 '17 at 1:24





You don't put tildes in the input file. Problem solved.

– chepner
Oct 21 '17 at 1:24










2 Answers
2






active

oldest

votes


















8














The POSIX standard imposes word expansion to be done in the following order (emphasize is mine):





  1. Tilde expansion (see Tilde Expansion), parameter expansion (see Parameter Expansion), command substitution (see Command Substitution),
    and arithmetic expansion (see Arithmetic Expansion) shall be
    performed, beginning to end. See item 5 in Token Recognition.


  2. Field splitting (see Field Splitting) shall be performed on the portions of the fields generated by step 1, unless IFS is null.


  3. Pathname expansion (see Pathname Expansion) shall be performed, unless set -f is in effect.


  4. Quote removal (see Quote Removal) shall always be performed last.





The only point which interests us here is the first one: as you can see tilde expansion is processed before parameter expansion:




  1. The shell attempts a tilde expansion on echo $x, there is no tilde to be found, so it proceeds.

  2. The shell attempts a parameter expansion on echo $x, $x is found and expanded and the command-line becomes echo ~/someDirectory.

  3. Processing continues, tilde expansion having already been processed the ~ character remains as-is.


By using the quotes while assigning the $x, you were explicitly requesting to not expand the tilde and treat it like a normal character. A thing often missed is that in shell commands you don't have to quote the whole string, so you can make the expansion happen right during the variable assignment:



user@host:~$ set -o xtrace
user@host:~$ x=~/'someDirectory'
+ x=/home/user/someDirectory
user@host:~$ echo $x
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


And you can also make the expansion occur on the echo command-line as long as it can happen before parameter expansion:



user@host:~$ x='someDirectory'
+ x=someDirectory
user@host:~$ echo ~/$x
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


If for some reason you really need to affect the tilde to the $x variable without expansion, and be able to expand it at the echo command, you must proceed in two times to force two expansions of the $x variable to occur:



user@host:~$ x='~/someDirectory'
+ x='~/someDirectory'
user@host:~$ echo "$( eval echo $x )"
++ eval echo '~/someDirectory'
+++ echo /home/user/someDirectory
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


However, be aware that depending on the context where you use such structure it may have unwanted side-effect. As a rule of thumb, prefer to avoid using anything requiring eval when you have another way.



If you want to specifically address the tilde issue as opposed to any other kind of expansion, such structure would be safer and portable:



user@host:~$ x='~/someDirectory'
+ x='~/someDirectory'
user@host:~$ case "$x" in "~/"*)
> x="${HOME}/${x#"~/"}"
> esac
+ case "$x" in
+ x=/home/user/someDirectory
user@host:~$ echo $x
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


This structure explicitly check the presence of a leading ~ and replaces it with the user home dir if it is found.



Following your comment, the x="${HOME}/${x#"~/"}" may indeed be surprising for someone not used in shell programming, but is in fact linked to the same POSIX rule I quoted above.



As imposed by the POSIX standard, quote removal happens last and parameter expansion happens very early. Thus, ${#"~"} is evaluated and expanded far before the evaluation of the outer quotes. In turns, as defined in Parameter expansion rules:




In each case that a value of word is needed (based on the state of
parameter, as described below), word shall be subjected to tilde
expansion, parameter expansion, command substitution, and arithmetic
expansion.




Thus, the right side of the # operator must be properly quoted or escaped to avoid tilde expansion.



So, to state it differently, when the shell interpretor looks at x="${HOME}/${x#"~/"}", he sees:





  1. ${HOME} and ${x#"~/"} must be expanded.


  2. ${HOME} is expanded to the content of the $HOME variable.


  3. ${x#"~/"} triggers a nested expansion: "~/" is parsed but, being quoted, is treated as a literal1. You could have used single quotes here with the same result.


  4. ${x#"~/"} expression itself is now expanded, resulting in the prefix ~/ being removed from the value of $x.

  5. The result of the above is now concatenated: the expansion of ${HOME}, the literal /, the expansion ${x#"~/"}.

  6. The end-result is enclosed in double-quotes, functionally preventing word splitting. I say functionally here because these double quotes are not technically required (see here and there for instance), but as a personal style as soon as an assignments gets anything beyond a=$b I usually find it clearer add double-quotes.


By-the-way, if look more closely to the case syntax, you will see the "~/"* construction which relies on the same concept as x=~/'someDirectory' I explained above (here again, double and simple quotes could be used interchangeably).



Don't worry if these things may seem obscure at the first sight (maybe even at the second or later sights!). In my opinion, parameter expansion are, with subshells, one of the most complex concept to grasp when programming in shell language.



I know that some people may vigorously disagree, but if you would-like to learn shell programming more in depth I encourage you to read the Advanced Bash Scripting Guide: it teaches Bash-scripting, so with a lot of extensions and bells-and-whistles compared to POSIX shell scripting, but I found it well written with loads of practical examples. Once you manage this, it is easy to restrict yourself to POSIX features when you need to, I personally think that entering directly in the POSIX realm is an unnecessary steep learning curve for beginners (compare my POSIX tilde replacement with @m0dular's regex-like Bash equivalent to get an idea of what I mean ;) !).





1: Which leads me into finding a bug in Dash which don't implement tilde expansion here correctly (verifiable using x='~/foo'; echo "${x#~/}"). Parameter expansion is a complex field both for the user and the shell developers themselves!






share|improve this answer


























  • How is the bash shell parsing the line x="${HOME}/${x#"~/"}"? It looks like a concatenation of 3 strings: "${HOME}/${x#", ~/, and "}". Does the shell allow for nested double-quotes when the inner pair of double quotes is inside a ${ } block?

    – Andrew
    Oct 21 '17 at 2:35











  • @Andrew: I have complete my answer with additional information hopefully addressing your comment.

    – WhiteWinterWolf
    Oct 21 '17 at 8:41











  • Thanks, this is a great answer. I've learned a ton from reading it. Wish I could upvote it more than once:)

    – Andrew
    Oct 21 '17 at 14:03











  • @WhiteWinterWolf: still, shell does not see the nested quotes whatever the result is.

    – avp
    Nov 22 '18 at 10:15



















4














One possible answer:



eval echo "$x"


Since you're reading input from a file, I would not do this.



You could search and replace the ~ with the value of $HOME, like this:



x='~/.config'
x="${x//~/$HOME}"
echo "$x"


Gives me:



/home/adrian/.config





share|improve this answer
























  • Note that the ${parameter/pattern/string} expansion is a Bash extension and may not be available in other shells.

    – WhiteWinterWolf
    Oct 20 '17 at 21:53











  • True. The OP did mention he was using Bash, so I think it's an appropriate answer.

    – m0dular
    Oct 20 '17 at 22:06











  • I agree, as long as one is sticking to Bash why not fully take advantage of it (not everybody need portability everywhere), but it's just worth to note it for non-Bash users (several distro now ship with Dash instead of Bash for instance) so affected users are not surprised.

    – WhiteWinterWolf
    Oct 20 '17 at 22:13











  • I took the liberty to mention your post in my digression about differences between Bash extensions and POSIX shell scripting, as I think that your Bash single-line regex-like statement compared to my POSIX case structure illustrate well how Bash scripting is more user-friendly specially for beginners.

    – WhiteWinterWolf
    Oct 21 '17 at 8:43














Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f399407%2fhow-can-i-expand-a-tilde-as-part-of-a-variable%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









8














The POSIX standard imposes word expansion to be done in the following order (emphasize is mine):





  1. Tilde expansion (see Tilde Expansion), parameter expansion (see Parameter Expansion), command substitution (see Command Substitution),
    and arithmetic expansion (see Arithmetic Expansion) shall be
    performed, beginning to end. See item 5 in Token Recognition.


  2. Field splitting (see Field Splitting) shall be performed on the portions of the fields generated by step 1, unless IFS is null.


  3. Pathname expansion (see Pathname Expansion) shall be performed, unless set -f is in effect.


  4. Quote removal (see Quote Removal) shall always be performed last.





The only point which interests us here is the first one: as you can see tilde expansion is processed before parameter expansion:




  1. The shell attempts a tilde expansion on echo $x, there is no tilde to be found, so it proceeds.

  2. The shell attempts a parameter expansion on echo $x, $x is found and expanded and the command-line becomes echo ~/someDirectory.

  3. Processing continues, tilde expansion having already been processed the ~ character remains as-is.


By using the quotes while assigning the $x, you were explicitly requesting to not expand the tilde and treat it like a normal character. A thing often missed is that in shell commands you don't have to quote the whole string, so you can make the expansion happen right during the variable assignment:



user@host:~$ set -o xtrace
user@host:~$ x=~/'someDirectory'
+ x=/home/user/someDirectory
user@host:~$ echo $x
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


And you can also make the expansion occur on the echo command-line as long as it can happen before parameter expansion:



user@host:~$ x='someDirectory'
+ x=someDirectory
user@host:~$ echo ~/$x
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


If for some reason you really need to affect the tilde to the $x variable without expansion, and be able to expand it at the echo command, you must proceed in two times to force two expansions of the $x variable to occur:



user@host:~$ x='~/someDirectory'
+ x='~/someDirectory'
user@host:~$ echo "$( eval echo $x )"
++ eval echo '~/someDirectory'
+++ echo /home/user/someDirectory
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


However, be aware that depending on the context where you use such structure it may have unwanted side-effect. As a rule of thumb, prefer to avoid using anything requiring eval when you have another way.



If you want to specifically address the tilde issue as opposed to any other kind of expansion, such structure would be safer and portable:



user@host:~$ x='~/someDirectory'
+ x='~/someDirectory'
user@host:~$ case "$x" in "~/"*)
> x="${HOME}/${x#"~/"}"
> esac
+ case "$x" in
+ x=/home/user/someDirectory
user@host:~$ echo $x
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


This structure explicitly check the presence of a leading ~ and replaces it with the user home dir if it is found.



Following your comment, the x="${HOME}/${x#"~/"}" may indeed be surprising for someone not used in shell programming, but is in fact linked to the same POSIX rule I quoted above.



As imposed by the POSIX standard, quote removal happens last and parameter expansion happens very early. Thus, ${#"~"} is evaluated and expanded far before the evaluation of the outer quotes. In turns, as defined in Parameter expansion rules:




In each case that a value of word is needed (based on the state of
parameter, as described below), word shall be subjected to tilde
expansion, parameter expansion, command substitution, and arithmetic
expansion.




Thus, the right side of the # operator must be properly quoted or escaped to avoid tilde expansion.



So, to state it differently, when the shell interpretor looks at x="${HOME}/${x#"~/"}", he sees:





  1. ${HOME} and ${x#"~/"} must be expanded.


  2. ${HOME} is expanded to the content of the $HOME variable.


  3. ${x#"~/"} triggers a nested expansion: "~/" is parsed but, being quoted, is treated as a literal1. You could have used single quotes here with the same result.


  4. ${x#"~/"} expression itself is now expanded, resulting in the prefix ~/ being removed from the value of $x.

  5. The result of the above is now concatenated: the expansion of ${HOME}, the literal /, the expansion ${x#"~/"}.

  6. The end-result is enclosed in double-quotes, functionally preventing word splitting. I say functionally here because these double quotes are not technically required (see here and there for instance), but as a personal style as soon as an assignments gets anything beyond a=$b I usually find it clearer add double-quotes.


By-the-way, if look more closely to the case syntax, you will see the "~/"* construction which relies on the same concept as x=~/'someDirectory' I explained above (here again, double and simple quotes could be used interchangeably).



Don't worry if these things may seem obscure at the first sight (maybe even at the second or later sights!). In my opinion, parameter expansion are, with subshells, one of the most complex concept to grasp when programming in shell language.



I know that some people may vigorously disagree, but if you would-like to learn shell programming more in depth I encourage you to read the Advanced Bash Scripting Guide: it teaches Bash-scripting, so with a lot of extensions and bells-and-whistles compared to POSIX shell scripting, but I found it well written with loads of practical examples. Once you manage this, it is easy to restrict yourself to POSIX features when you need to, I personally think that entering directly in the POSIX realm is an unnecessary steep learning curve for beginners (compare my POSIX tilde replacement with @m0dular's regex-like Bash equivalent to get an idea of what I mean ;) !).





1: Which leads me into finding a bug in Dash which don't implement tilde expansion here correctly (verifiable using x='~/foo'; echo "${x#~/}"). Parameter expansion is a complex field both for the user and the shell developers themselves!






share|improve this answer


























  • How is the bash shell parsing the line x="${HOME}/${x#"~/"}"? It looks like a concatenation of 3 strings: "${HOME}/${x#", ~/, and "}". Does the shell allow for nested double-quotes when the inner pair of double quotes is inside a ${ } block?

    – Andrew
    Oct 21 '17 at 2:35











  • @Andrew: I have complete my answer with additional information hopefully addressing your comment.

    – WhiteWinterWolf
    Oct 21 '17 at 8:41











  • Thanks, this is a great answer. I've learned a ton from reading it. Wish I could upvote it more than once:)

    – Andrew
    Oct 21 '17 at 14:03











  • @WhiteWinterWolf: still, shell does not see the nested quotes whatever the result is.

    – avp
    Nov 22 '18 at 10:15
















8














The POSIX standard imposes word expansion to be done in the following order (emphasize is mine):





  1. Tilde expansion (see Tilde Expansion), parameter expansion (see Parameter Expansion), command substitution (see Command Substitution),
    and arithmetic expansion (see Arithmetic Expansion) shall be
    performed, beginning to end. See item 5 in Token Recognition.


  2. Field splitting (see Field Splitting) shall be performed on the portions of the fields generated by step 1, unless IFS is null.


  3. Pathname expansion (see Pathname Expansion) shall be performed, unless set -f is in effect.


  4. Quote removal (see Quote Removal) shall always be performed last.





The only point which interests us here is the first one: as you can see tilde expansion is processed before parameter expansion:




  1. The shell attempts a tilde expansion on echo $x, there is no tilde to be found, so it proceeds.

  2. The shell attempts a parameter expansion on echo $x, $x is found and expanded and the command-line becomes echo ~/someDirectory.

  3. Processing continues, tilde expansion having already been processed the ~ character remains as-is.


By using the quotes while assigning the $x, you were explicitly requesting to not expand the tilde and treat it like a normal character. A thing often missed is that in shell commands you don't have to quote the whole string, so you can make the expansion happen right during the variable assignment:



user@host:~$ set -o xtrace
user@host:~$ x=~/'someDirectory'
+ x=/home/user/someDirectory
user@host:~$ echo $x
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


And you can also make the expansion occur on the echo command-line as long as it can happen before parameter expansion:



user@host:~$ x='someDirectory'
+ x=someDirectory
user@host:~$ echo ~/$x
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


If for some reason you really need to affect the tilde to the $x variable without expansion, and be able to expand it at the echo command, you must proceed in two times to force two expansions of the $x variable to occur:



user@host:~$ x='~/someDirectory'
+ x='~/someDirectory'
user@host:~$ echo "$( eval echo $x )"
++ eval echo '~/someDirectory'
+++ echo /home/user/someDirectory
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


However, be aware that depending on the context where you use such structure it may have unwanted side-effect. As a rule of thumb, prefer to avoid using anything requiring eval when you have another way.



If you want to specifically address the tilde issue as opposed to any other kind of expansion, such structure would be safer and portable:



user@host:~$ x='~/someDirectory'
+ x='~/someDirectory'
user@host:~$ case "$x" in "~/"*)
> x="${HOME}/${x#"~/"}"
> esac
+ case "$x" in
+ x=/home/user/someDirectory
user@host:~$ echo $x
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


This structure explicitly check the presence of a leading ~ and replaces it with the user home dir if it is found.



Following your comment, the x="${HOME}/${x#"~/"}" may indeed be surprising for someone not used in shell programming, but is in fact linked to the same POSIX rule I quoted above.



As imposed by the POSIX standard, quote removal happens last and parameter expansion happens very early. Thus, ${#"~"} is evaluated and expanded far before the evaluation of the outer quotes. In turns, as defined in Parameter expansion rules:




In each case that a value of word is needed (based on the state of
parameter, as described below), word shall be subjected to tilde
expansion, parameter expansion, command substitution, and arithmetic
expansion.




Thus, the right side of the # operator must be properly quoted or escaped to avoid tilde expansion.



So, to state it differently, when the shell interpretor looks at x="${HOME}/${x#"~/"}", he sees:





  1. ${HOME} and ${x#"~/"} must be expanded.


  2. ${HOME} is expanded to the content of the $HOME variable.


  3. ${x#"~/"} triggers a nested expansion: "~/" is parsed but, being quoted, is treated as a literal1. You could have used single quotes here with the same result.


  4. ${x#"~/"} expression itself is now expanded, resulting in the prefix ~/ being removed from the value of $x.

  5. The result of the above is now concatenated: the expansion of ${HOME}, the literal /, the expansion ${x#"~/"}.

  6. The end-result is enclosed in double-quotes, functionally preventing word splitting. I say functionally here because these double quotes are not technically required (see here and there for instance), but as a personal style as soon as an assignments gets anything beyond a=$b I usually find it clearer add double-quotes.


By-the-way, if look more closely to the case syntax, you will see the "~/"* construction which relies on the same concept as x=~/'someDirectory' I explained above (here again, double and simple quotes could be used interchangeably).



Don't worry if these things may seem obscure at the first sight (maybe even at the second or later sights!). In my opinion, parameter expansion are, with subshells, one of the most complex concept to grasp when programming in shell language.



I know that some people may vigorously disagree, but if you would-like to learn shell programming more in depth I encourage you to read the Advanced Bash Scripting Guide: it teaches Bash-scripting, so with a lot of extensions and bells-and-whistles compared to POSIX shell scripting, but I found it well written with loads of practical examples. Once you manage this, it is easy to restrict yourself to POSIX features when you need to, I personally think that entering directly in the POSIX realm is an unnecessary steep learning curve for beginners (compare my POSIX tilde replacement with @m0dular's regex-like Bash equivalent to get an idea of what I mean ;) !).





1: Which leads me into finding a bug in Dash which don't implement tilde expansion here correctly (verifiable using x='~/foo'; echo "${x#~/}"). Parameter expansion is a complex field both for the user and the shell developers themselves!






share|improve this answer


























  • How is the bash shell parsing the line x="${HOME}/${x#"~/"}"? It looks like a concatenation of 3 strings: "${HOME}/${x#", ~/, and "}". Does the shell allow for nested double-quotes when the inner pair of double quotes is inside a ${ } block?

    – Andrew
    Oct 21 '17 at 2:35











  • @Andrew: I have complete my answer with additional information hopefully addressing your comment.

    – WhiteWinterWolf
    Oct 21 '17 at 8:41











  • Thanks, this is a great answer. I've learned a ton from reading it. Wish I could upvote it more than once:)

    – Andrew
    Oct 21 '17 at 14:03











  • @WhiteWinterWolf: still, shell does not see the nested quotes whatever the result is.

    – avp
    Nov 22 '18 at 10:15














8












8








8







The POSIX standard imposes word expansion to be done in the following order (emphasize is mine):





  1. Tilde expansion (see Tilde Expansion), parameter expansion (see Parameter Expansion), command substitution (see Command Substitution),
    and arithmetic expansion (see Arithmetic Expansion) shall be
    performed, beginning to end. See item 5 in Token Recognition.


  2. Field splitting (see Field Splitting) shall be performed on the portions of the fields generated by step 1, unless IFS is null.


  3. Pathname expansion (see Pathname Expansion) shall be performed, unless set -f is in effect.


  4. Quote removal (see Quote Removal) shall always be performed last.





The only point which interests us here is the first one: as you can see tilde expansion is processed before parameter expansion:




  1. The shell attempts a tilde expansion on echo $x, there is no tilde to be found, so it proceeds.

  2. The shell attempts a parameter expansion on echo $x, $x is found and expanded and the command-line becomes echo ~/someDirectory.

  3. Processing continues, tilde expansion having already been processed the ~ character remains as-is.


By using the quotes while assigning the $x, you were explicitly requesting to not expand the tilde and treat it like a normal character. A thing often missed is that in shell commands you don't have to quote the whole string, so you can make the expansion happen right during the variable assignment:



user@host:~$ set -o xtrace
user@host:~$ x=~/'someDirectory'
+ x=/home/user/someDirectory
user@host:~$ echo $x
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


And you can also make the expansion occur on the echo command-line as long as it can happen before parameter expansion:



user@host:~$ x='someDirectory'
+ x=someDirectory
user@host:~$ echo ~/$x
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


If for some reason you really need to affect the tilde to the $x variable without expansion, and be able to expand it at the echo command, you must proceed in two times to force two expansions of the $x variable to occur:



user@host:~$ x='~/someDirectory'
+ x='~/someDirectory'
user@host:~$ echo "$( eval echo $x )"
++ eval echo '~/someDirectory'
+++ echo /home/user/someDirectory
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


However, be aware that depending on the context where you use such structure it may have unwanted side-effect. As a rule of thumb, prefer to avoid using anything requiring eval when you have another way.



If you want to specifically address the tilde issue as opposed to any other kind of expansion, such structure would be safer and portable:



user@host:~$ x='~/someDirectory'
+ x='~/someDirectory'
user@host:~$ case "$x" in "~/"*)
> x="${HOME}/${x#"~/"}"
> esac
+ case "$x" in
+ x=/home/user/someDirectory
user@host:~$ echo $x
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


This structure explicitly check the presence of a leading ~ and replaces it with the user home dir if it is found.



Following your comment, the x="${HOME}/${x#"~/"}" may indeed be surprising for someone not used in shell programming, but is in fact linked to the same POSIX rule I quoted above.



As imposed by the POSIX standard, quote removal happens last and parameter expansion happens very early. Thus, ${#"~"} is evaluated and expanded far before the evaluation of the outer quotes. In turns, as defined in Parameter expansion rules:




In each case that a value of word is needed (based on the state of
parameter, as described below), word shall be subjected to tilde
expansion, parameter expansion, command substitution, and arithmetic
expansion.




Thus, the right side of the # operator must be properly quoted or escaped to avoid tilde expansion.



So, to state it differently, when the shell interpretor looks at x="${HOME}/${x#"~/"}", he sees:





  1. ${HOME} and ${x#"~/"} must be expanded.


  2. ${HOME} is expanded to the content of the $HOME variable.


  3. ${x#"~/"} triggers a nested expansion: "~/" is parsed but, being quoted, is treated as a literal1. You could have used single quotes here with the same result.


  4. ${x#"~/"} expression itself is now expanded, resulting in the prefix ~/ being removed from the value of $x.

  5. The result of the above is now concatenated: the expansion of ${HOME}, the literal /, the expansion ${x#"~/"}.

  6. The end-result is enclosed in double-quotes, functionally preventing word splitting. I say functionally here because these double quotes are not technically required (see here and there for instance), but as a personal style as soon as an assignments gets anything beyond a=$b I usually find it clearer add double-quotes.


By-the-way, if look more closely to the case syntax, you will see the "~/"* construction which relies on the same concept as x=~/'someDirectory' I explained above (here again, double and simple quotes could be used interchangeably).



Don't worry if these things may seem obscure at the first sight (maybe even at the second or later sights!). In my opinion, parameter expansion are, with subshells, one of the most complex concept to grasp when programming in shell language.



I know that some people may vigorously disagree, but if you would-like to learn shell programming more in depth I encourage you to read the Advanced Bash Scripting Guide: it teaches Bash-scripting, so with a lot of extensions and bells-and-whistles compared to POSIX shell scripting, but I found it well written with loads of practical examples. Once you manage this, it is easy to restrict yourself to POSIX features when you need to, I personally think that entering directly in the POSIX realm is an unnecessary steep learning curve for beginners (compare my POSIX tilde replacement with @m0dular's regex-like Bash equivalent to get an idea of what I mean ;) !).





1: Which leads me into finding a bug in Dash which don't implement tilde expansion here correctly (verifiable using x='~/foo'; echo "${x#~/}"). Parameter expansion is a complex field both for the user and the shell developers themselves!






share|improve this answer















The POSIX standard imposes word expansion to be done in the following order (emphasize is mine):





  1. Tilde expansion (see Tilde Expansion), parameter expansion (see Parameter Expansion), command substitution (see Command Substitution),
    and arithmetic expansion (see Arithmetic Expansion) shall be
    performed, beginning to end. See item 5 in Token Recognition.


  2. Field splitting (see Field Splitting) shall be performed on the portions of the fields generated by step 1, unless IFS is null.


  3. Pathname expansion (see Pathname Expansion) shall be performed, unless set -f is in effect.


  4. Quote removal (see Quote Removal) shall always be performed last.





The only point which interests us here is the first one: as you can see tilde expansion is processed before parameter expansion:




  1. The shell attempts a tilde expansion on echo $x, there is no tilde to be found, so it proceeds.

  2. The shell attempts a parameter expansion on echo $x, $x is found and expanded and the command-line becomes echo ~/someDirectory.

  3. Processing continues, tilde expansion having already been processed the ~ character remains as-is.


By using the quotes while assigning the $x, you were explicitly requesting to not expand the tilde and treat it like a normal character. A thing often missed is that in shell commands you don't have to quote the whole string, so you can make the expansion happen right during the variable assignment:



user@host:~$ set -o xtrace
user@host:~$ x=~/'someDirectory'
+ x=/home/user/someDirectory
user@host:~$ echo $x
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


And you can also make the expansion occur on the echo command-line as long as it can happen before parameter expansion:



user@host:~$ x='someDirectory'
+ x=someDirectory
user@host:~$ echo ~/$x
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


If for some reason you really need to affect the tilde to the $x variable without expansion, and be able to expand it at the echo command, you must proceed in two times to force two expansions of the $x variable to occur:



user@host:~$ x='~/someDirectory'
+ x='~/someDirectory'
user@host:~$ echo "$( eval echo $x )"
++ eval echo '~/someDirectory'
+++ echo /home/user/someDirectory
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


However, be aware that depending on the context where you use such structure it may have unwanted side-effect. As a rule of thumb, prefer to avoid using anything requiring eval when you have another way.



If you want to specifically address the tilde issue as opposed to any other kind of expansion, such structure would be safer and portable:



user@host:~$ x='~/someDirectory'
+ x='~/someDirectory'
user@host:~$ case "$x" in "~/"*)
> x="${HOME}/${x#"~/"}"
> esac
+ case "$x" in
+ x=/home/user/someDirectory
user@host:~$ echo $x
+ echo /home/user/someDirectory
/home/user/someDirectory
user@host:~$


This structure explicitly check the presence of a leading ~ and replaces it with the user home dir if it is found.



Following your comment, the x="${HOME}/${x#"~/"}" may indeed be surprising for someone not used in shell programming, but is in fact linked to the same POSIX rule I quoted above.



As imposed by the POSIX standard, quote removal happens last and parameter expansion happens very early. Thus, ${#"~"} is evaluated and expanded far before the evaluation of the outer quotes. In turns, as defined in Parameter expansion rules:




In each case that a value of word is needed (based on the state of
parameter, as described below), word shall be subjected to tilde
expansion, parameter expansion, command substitution, and arithmetic
expansion.




Thus, the right side of the # operator must be properly quoted or escaped to avoid tilde expansion.



So, to state it differently, when the shell interpretor looks at x="${HOME}/${x#"~/"}", he sees:





  1. ${HOME} and ${x#"~/"} must be expanded.


  2. ${HOME} is expanded to the content of the $HOME variable.


  3. ${x#"~/"} triggers a nested expansion: "~/" is parsed but, being quoted, is treated as a literal1. You could have used single quotes here with the same result.


  4. ${x#"~/"} expression itself is now expanded, resulting in the prefix ~/ being removed from the value of $x.

  5. The result of the above is now concatenated: the expansion of ${HOME}, the literal /, the expansion ${x#"~/"}.

  6. The end-result is enclosed in double-quotes, functionally preventing word splitting. I say functionally here because these double quotes are not technically required (see here and there for instance), but as a personal style as soon as an assignments gets anything beyond a=$b I usually find it clearer add double-quotes.


By-the-way, if look more closely to the case syntax, you will see the "~/"* construction which relies on the same concept as x=~/'someDirectory' I explained above (here again, double and simple quotes could be used interchangeably).



Don't worry if these things may seem obscure at the first sight (maybe even at the second or later sights!). In my opinion, parameter expansion are, with subshells, one of the most complex concept to grasp when programming in shell language.



I know that some people may vigorously disagree, but if you would-like to learn shell programming more in depth I encourage you to read the Advanced Bash Scripting Guide: it teaches Bash-scripting, so with a lot of extensions and bells-and-whistles compared to POSIX shell scripting, but I found it well written with loads of practical examples. Once you manage this, it is easy to restrict yourself to POSIX features when you need to, I personally think that entering directly in the POSIX realm is an unnecessary steep learning curve for beginners (compare my POSIX tilde replacement with @m0dular's regex-like Bash equivalent to get an idea of what I mean ;) !).





1: Which leads me into finding a bug in Dash which don't implement tilde expansion here correctly (verifiable using x='~/foo'; echo "${x#~/}"). Parameter expansion is a complex field both for the user and the shell developers themselves!







share|improve this answer














share|improve this answer



share|improve this answer








edited Oct 21 '17 at 8:40

























answered Oct 20 '17 at 21:33









WhiteWinterWolfWhiteWinterWolf

1,74610 silver badges31 bronze badges




1,74610 silver badges31 bronze badges













  • How is the bash shell parsing the line x="${HOME}/${x#"~/"}"? It looks like a concatenation of 3 strings: "${HOME}/${x#", ~/, and "}". Does the shell allow for nested double-quotes when the inner pair of double quotes is inside a ${ } block?

    – Andrew
    Oct 21 '17 at 2:35











  • @Andrew: I have complete my answer with additional information hopefully addressing your comment.

    – WhiteWinterWolf
    Oct 21 '17 at 8:41











  • Thanks, this is a great answer. I've learned a ton from reading it. Wish I could upvote it more than once:)

    – Andrew
    Oct 21 '17 at 14:03











  • @WhiteWinterWolf: still, shell does not see the nested quotes whatever the result is.

    – avp
    Nov 22 '18 at 10:15



















  • How is the bash shell parsing the line x="${HOME}/${x#"~/"}"? It looks like a concatenation of 3 strings: "${HOME}/${x#", ~/, and "}". Does the shell allow for nested double-quotes when the inner pair of double quotes is inside a ${ } block?

    – Andrew
    Oct 21 '17 at 2:35











  • @Andrew: I have complete my answer with additional information hopefully addressing your comment.

    – WhiteWinterWolf
    Oct 21 '17 at 8:41











  • Thanks, this is a great answer. I've learned a ton from reading it. Wish I could upvote it more than once:)

    – Andrew
    Oct 21 '17 at 14:03











  • @WhiteWinterWolf: still, shell does not see the nested quotes whatever the result is.

    – avp
    Nov 22 '18 at 10:15

















How is the bash shell parsing the line x="${HOME}/${x#"~/"}"? It looks like a concatenation of 3 strings: "${HOME}/${x#", ~/, and "}". Does the shell allow for nested double-quotes when the inner pair of double quotes is inside a ${ } block?

– Andrew
Oct 21 '17 at 2:35





How is the bash shell parsing the line x="${HOME}/${x#"~/"}"? It looks like a concatenation of 3 strings: "${HOME}/${x#", ~/, and "}". Does the shell allow for nested double-quotes when the inner pair of double quotes is inside a ${ } block?

– Andrew
Oct 21 '17 at 2:35













@Andrew: I have complete my answer with additional information hopefully addressing your comment.

– WhiteWinterWolf
Oct 21 '17 at 8:41





@Andrew: I have complete my answer with additional information hopefully addressing your comment.

– WhiteWinterWolf
Oct 21 '17 at 8:41













Thanks, this is a great answer. I've learned a ton from reading it. Wish I could upvote it more than once:)

– Andrew
Oct 21 '17 at 14:03





Thanks, this is a great answer. I've learned a ton from reading it. Wish I could upvote it more than once:)

– Andrew
Oct 21 '17 at 14:03













@WhiteWinterWolf: still, shell does not see the nested quotes whatever the result is.

– avp
Nov 22 '18 at 10:15





@WhiteWinterWolf: still, shell does not see the nested quotes whatever the result is.

– avp
Nov 22 '18 at 10:15













4














One possible answer:



eval echo "$x"


Since you're reading input from a file, I would not do this.



You could search and replace the ~ with the value of $HOME, like this:



x='~/.config'
x="${x//~/$HOME}"
echo "$x"


Gives me:



/home/adrian/.config





share|improve this answer
























  • Note that the ${parameter/pattern/string} expansion is a Bash extension and may not be available in other shells.

    – WhiteWinterWolf
    Oct 20 '17 at 21:53











  • True. The OP did mention he was using Bash, so I think it's an appropriate answer.

    – m0dular
    Oct 20 '17 at 22:06











  • I agree, as long as one is sticking to Bash why not fully take advantage of it (not everybody need portability everywhere), but it's just worth to note it for non-Bash users (several distro now ship with Dash instead of Bash for instance) so affected users are not surprised.

    – WhiteWinterWolf
    Oct 20 '17 at 22:13











  • I took the liberty to mention your post in my digression about differences between Bash extensions and POSIX shell scripting, as I think that your Bash single-line regex-like statement compared to my POSIX case structure illustrate well how Bash scripting is more user-friendly specially for beginners.

    – WhiteWinterWolf
    Oct 21 '17 at 8:43
















4














One possible answer:



eval echo "$x"


Since you're reading input from a file, I would not do this.



You could search and replace the ~ with the value of $HOME, like this:



x='~/.config'
x="${x//~/$HOME}"
echo "$x"


Gives me:



/home/adrian/.config





share|improve this answer
























  • Note that the ${parameter/pattern/string} expansion is a Bash extension and may not be available in other shells.

    – WhiteWinterWolf
    Oct 20 '17 at 21:53











  • True. The OP did mention he was using Bash, so I think it's an appropriate answer.

    – m0dular
    Oct 20 '17 at 22:06











  • I agree, as long as one is sticking to Bash why not fully take advantage of it (not everybody need portability everywhere), but it's just worth to note it for non-Bash users (several distro now ship with Dash instead of Bash for instance) so affected users are not surprised.

    – WhiteWinterWolf
    Oct 20 '17 at 22:13











  • I took the liberty to mention your post in my digression about differences between Bash extensions and POSIX shell scripting, as I think that your Bash single-line regex-like statement compared to my POSIX case structure illustrate well how Bash scripting is more user-friendly specially for beginners.

    – WhiteWinterWolf
    Oct 21 '17 at 8:43














4












4








4







One possible answer:



eval echo "$x"


Since you're reading input from a file, I would not do this.



You could search and replace the ~ with the value of $HOME, like this:



x='~/.config'
x="${x//~/$HOME}"
echo "$x"


Gives me:



/home/adrian/.config





share|improve this answer













One possible answer:



eval echo "$x"


Since you're reading input from a file, I would not do this.



You could search and replace the ~ with the value of $HOME, like this:



x='~/.config'
x="${x//~/$HOME}"
echo "$x"


Gives me:



/home/adrian/.config






share|improve this answer












share|improve this answer



share|improve this answer










answered Oct 20 '17 at 21:38









m0dularm0dular

8462 silver badges6 bronze badges




8462 silver badges6 bronze badges













  • Note that the ${parameter/pattern/string} expansion is a Bash extension and may not be available in other shells.

    – WhiteWinterWolf
    Oct 20 '17 at 21:53











  • True. The OP did mention he was using Bash, so I think it's an appropriate answer.

    – m0dular
    Oct 20 '17 at 22:06











  • I agree, as long as one is sticking to Bash why not fully take advantage of it (not everybody need portability everywhere), but it's just worth to note it for non-Bash users (several distro now ship with Dash instead of Bash for instance) so affected users are not surprised.

    – WhiteWinterWolf
    Oct 20 '17 at 22:13











  • I took the liberty to mention your post in my digression about differences between Bash extensions and POSIX shell scripting, as I think that your Bash single-line regex-like statement compared to my POSIX case structure illustrate well how Bash scripting is more user-friendly specially for beginners.

    – WhiteWinterWolf
    Oct 21 '17 at 8:43



















  • Note that the ${parameter/pattern/string} expansion is a Bash extension and may not be available in other shells.

    – WhiteWinterWolf
    Oct 20 '17 at 21:53











  • True. The OP did mention he was using Bash, so I think it's an appropriate answer.

    – m0dular
    Oct 20 '17 at 22:06











  • I agree, as long as one is sticking to Bash why not fully take advantage of it (not everybody need portability everywhere), but it's just worth to note it for non-Bash users (several distro now ship with Dash instead of Bash for instance) so affected users are not surprised.

    – WhiteWinterWolf
    Oct 20 '17 at 22:13











  • I took the liberty to mention your post in my digression about differences between Bash extensions and POSIX shell scripting, as I think that your Bash single-line regex-like statement compared to my POSIX case structure illustrate well how Bash scripting is more user-friendly specially for beginners.

    – WhiteWinterWolf
    Oct 21 '17 at 8:43

















Note that the ${parameter/pattern/string} expansion is a Bash extension and may not be available in other shells.

– WhiteWinterWolf
Oct 20 '17 at 21:53





Note that the ${parameter/pattern/string} expansion is a Bash extension and may not be available in other shells.

– WhiteWinterWolf
Oct 20 '17 at 21:53













True. The OP did mention he was using Bash, so I think it's an appropriate answer.

– m0dular
Oct 20 '17 at 22:06





True. The OP did mention he was using Bash, so I think it's an appropriate answer.

– m0dular
Oct 20 '17 at 22:06













I agree, as long as one is sticking to Bash why not fully take advantage of it (not everybody need portability everywhere), but it's just worth to note it for non-Bash users (several distro now ship with Dash instead of Bash for instance) so affected users are not surprised.

– WhiteWinterWolf
Oct 20 '17 at 22:13





I agree, as long as one is sticking to Bash why not fully take advantage of it (not everybody need portability everywhere), but it's just worth to note it for non-Bash users (several distro now ship with Dash instead of Bash for instance) so affected users are not surprised.

– WhiteWinterWolf
Oct 20 '17 at 22:13













I took the liberty to mention your post in my digression about differences between Bash extensions and POSIX shell scripting, as I think that your Bash single-line regex-like statement compared to my POSIX case structure illustrate well how Bash scripting is more user-friendly specially for beginners.

– WhiteWinterWolf
Oct 21 '17 at 8:43





I took the liberty to mention your post in my digression about differences between Bash extensions and POSIX shell scripting, as I think that your Bash single-line regex-like statement compared to my POSIX case structure illustrate well how Bash scripting is more user-friendly specially for beginners.

– WhiteWinterWolf
Oct 21 '17 at 8:43


















draft saved

draft discarded




















































Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f399407%2fhow-can-i-expand-a-tilde-as-part-of-a-variable%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Taj Mahal Inhaltsverzeichnis Aufbau | Geschichte | 350-Jahr-Feier | Heutige Bedeutung | Siehe auch |...

Baia Sprie Cuprins Etimologie | Istorie | Demografie | Politică și administrație | Arii naturale...

Ciclooctatetraenă Vezi și | Bibliografie | Meniu de navigare637866text4148569-500570979m