LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   dynamic variable contents $() ? (https://www.linuxquestions.org/questions/linux-newbie-8/dynamic-variable-contents-%24-4175528629/)

szejiekoh 12-18-2014 01:37 AM

dynamic variable contents $() ?
 
Hi all,

I am new to linux and learning to use PS1. It came to me that if i set
PS1=`date` , the date is always static. Meaning it doesnt reflect the current date.

Code:

Thu Dec 18 15:30:01 SGT 2014 >PS1=" `date` > "
 Thu Dec 18 15:30:03 SGT 2014 >
 Thu Dec 18 15:30:03 SGT 2014 >
 Thu Dec 18 15:30:03 SGT 2014 >
 Thu Dec 18 15:30:03 SGT 2014 >

If i set it to $(date), it is still the same.

Quote:

Thu Dec 18 15:30:03 SGT 2014 > PS1=" $(date) > "
Thu Dec 18 15:30:42 SGT 2014 >
Thu Dec 18 15:30:42 SGT 2014 >
Thu Dec 18 15:30:42 SGT 2014 >
Thu Dec 18 15:30:42 SGT 2014 >
Thu Dec 18 15:30:42 SGT 2014 >
But if i add a backslash "\" infront, the dates are updated dynamically.

Quote:

Thu Dec 18 15:35:54 SGT 2014 > PS1=" \$(date) > "
Thu Dec 18 15:35:58 SGT 2014 >
Thu Dec 18 15:35:59 SGT 2014 >
Thu Dec 18 15:36:00 SGT 2014 >
Thu Dec 18 15:36:02 SGT 2014 >
q1) what does $() means ? is it the same meaning as `` ?
q2) why adding a \ works ? what does \ means then in this scenario?

Regards,
Noob

grail 12-18-2014 02:24 AM

$() is the modern replacement for `` but in addition it allows additional features such as nesting which can be extremely difficult if not impossible at times using ``

As for why escaping (placing a slosh (\) prior to a character) allows it to be more dynamic, you are setting the prompt to the string '$(date)' which is then evaluated by the shell each time you hit enter.

There are escape sequences you can use to do the same ... here is the one I use at work currently:
Code:

PS1='\[\e[1;33m\][\D{%d-%m-%Y %H:%M.%S}] \[\e[1;32m\]\w\n\[\e[1;36m\][\u.\h]\[\e[0m\]$ '

SAbhi 12-18-2014 02:55 AM

a) not that much different but backticks have a slight different treatment for backslashes and some other special characters than $()
though they does the same when provided with something to execute.
$() can be easily nested while backticks to be nested takes to escape likes of them to be read as backticks.

POSIX has a good info.

b) PS1 itself in bashrc executes something listed inside it and since without escaping the $ it doesnt know it would need to run the date command again it stored the one time output as if read at startup.

if i were incorrect anywhere above, someone should come and correct.

szejiekoh 12-18-2014 01:00 PM

Hi Grail and sabhi, thanks for replying.


Quote:

Originally Posted by grail (Post 5286803)
$() is the modern replacement for `` but in addition it allows additional features such as nesting which can be extremely difficult if not impossible at times using ``

As for why escaping (placing a slosh (\) prior to a character) allows it to be more dynamic, you are setting the prompt to the string '$(date)' which is then evaluated by the shell each time you hit enter.

There are escape sequences you can use to do the same ... here is the one I use at work currently:
Code:

PS1='\[\e[1;33m\][\D{%d-%m-%Y %H:%M.%S}] \[\e[1;32m\]\w\n\[\e[1;36m\][\u.\h]\[\e[0m\]$ '


Hi Grail, yes i am setting the prompt (PS1) to the string $(date), but if i dont put a \, it is only evaulated once. But if i put a \, it is evaluated everytime.

What does the "\" means then ? $(date) \$(date)
Does it means to instruct the shell to evaluate everytime instead of 1 time ?

Regards
Noob

suicidaleggroll 12-18-2014 01:11 PM

Quote:

Originally Posted by szejiekoh (Post 5287022)
Hi Grail and sabhi, thanks for replying.





Hi Grail, yes i am setting the prompt (PS1) to the string $(date), but if i dont put a \, it is only evaulated once. But if i put a \, it is evaluated everytime.

What does the "\" means then ? $(date) \$(date)
Does it means to instruct the shell to evaluate everytime instead of 1 time ?

Regards
Noob

If you don't use the backslash, then you aren't setting PS1 to the string "$(date)", you're setting PS1 to the OUTPUT of the command $(date) when you ran the command. The $(date) is being executed first, and the result is set to PS1. So when you run export PS1="$(date)", the ACTUAL command is export PS1="Thu Dec 18 12:07:29 MST 2014" (or whatever your current date is). It's easiest to see the difference if you just echo the contents of PS1.

Code:

$ export PS1="$(date) > "
Thu Dec 18 12:07:29 MST 2014 > echo $PS1
Thu Dec 18 12:07:29 MST 2014 >
Thu Dec 18 12:07:29 MST 2014 > export PS1="\$(date) > "
Thu Dec 18 12:08:01 MST 2014 > echo $PS1
$(date) >

See the difference? Without the backslash, $(date) gets evaluated at the time you set PS1. So PS1 is not set to $(date), it's set to the literal string "Thu Dec 18 12:07:29 MST 2014" (or whatever your current date/time happened to be). With the backslash, the $(date) command is not evaluated until PS1 is used, rather than when it's set. You can accomplish the same thing by using single quotes instead of double:
Code:

export PS1='$(date) > '
Like with the backslash, variables or functions inside single quotes don't get evaluated until they're used. Similar to:

Code:

$ a=5
$ b=$a
$ echo $b
5
$ b='$a'
$ echo $b
$a
$ eval echo $b
5

People get into the same kind of trouble with ssh:
Code:

$ ssh server "echo $HOSTNAME"
client
$ ssh server 'echo $HOSTNAME'
server

With double quotes, the variable $HOSTNAME is expanded before ssh is even called, so your ssh command is actually "ssh server echo client". With single quotes (or if you had put a backslash in front), the literal string "$HOSTNAME" is sent through ssh, where it's evaluated on the server.

When you start nesting commands or variables like this, you need to pay close attention to WHEN and WHERE your command is actually being executed (or when/where your variable expansion is actually taking place, as the case may be).

szejiekoh 12-19-2014 01:31 AM

Quote:

Originally Posted by suicidaleggroll (Post 5287029)
If you don't use the backslash, then you aren't setting PS1 to the string "$(date)", you're setting PS1 to the OUTPUT of the command $(date) when you ran the command. The $(date) is being executed first, and the result is set to PS1. So when you run export PS1="$(date)", the ACTUAL command is export PS1="Thu Dec 18 12:07:29 MST 2014" (or whatever your current date is). It's easiest to see the difference if you just echo the contents of PS1.

Code:

$ export PS1="$(date) > "
Thu Dec 18 12:07:29 MST 2014 > echo $PS1
Thu Dec 18 12:07:29 MST 2014 >
Thu Dec 18 12:07:29 MST 2014 > export PS1="\$(date) > "
Thu Dec 18 12:08:01 MST 2014 > echo $PS1
$(date) >

See the difference? Without the backslash, $(date) gets evaluated at the time you set PS1. So PS1 is not set to $(date), it's set to the literal string "Thu Dec 18 12:07:29 MST 2014" (or whatever your current date/time happened to be). With the backslash, the $(date) command is not evaluated until PS1 is used, rather than when it's set. You can accomplish the same thing by using single quotes instead of double:
Code:

export PS1='$(date) > '
Like with the backslash, variables or functions inside single quotes don't get evaluated until they're used. Similar to:

Code:

$ a=5
$ b=$a
$ echo $b
5
$ b='$a'
$ echo $b
$a
$ eval echo $b
5

People get into the same kind of trouble with ssh:
Code:

$ ssh server "echo $HOSTNAME"
client
$ ssh server 'echo $HOSTNAME'
server

With double quotes, the variable $HOSTNAME is expanded before ssh is even called, so your ssh command is actually "ssh server echo client". With single quotes (or if you had put a backslash in front), the literal string "$HOSTNAME" is sent through ssh, where it's evaluated on the server.

When you start nesting commands or variables like this, you need to pay close attention to WHEN and WHERE your command is actually being executed (or when/where your variable expansion is actually taking place, as the case may be).

Hi suicidal,

Thanks. Appreciate the detailed explanation.

Regards,
Noob

grail 12-19-2014 01:49 AM

Please mark as SOLVED once you have a solution / answer

acoustee3012 12-19-2014 01:52 AM

Nice job, tks u bro

szejiekoh 12-20-2014 01:36 PM

Quote:

Originally Posted by grail (Post 5287380)
Please mark as SOLVED once you have a solution / answer


Noted Grail. Done that already..

Thanks.


All times are GMT -5. The time now is 04:42 AM.