[TriLUG] Changing slashes to backslashes in prompt

Stephen P. Schaefer via TriLUG trilug at trilug.org
Fri Apr 19 18:02:38 EDT 2019


Yes, you should try to pretend that a linux shell is anything like
Windows cmd prompt, but the Linux shell is Turing equivalent (ignoring
various value limits induced by variable bits and RAM size that render
it, like any actual program, a finite state machine), so if the problem
is Turing evaluable, as this one is, the shell can do it; the question
is "merely" how elegantly it can do so.

Here's how I approached this.

First, I checked what my default PS1 was doing, since, by default it is
set to show the basename of the directory I'm in.  So

[sps at corydon ~]$ set | grep PS1
GUESTFISH_PS1='\[\e[1;32m\]><fs>\[\e[0;31m\] '
PS1='[\u@\h \W]\$ '

(you can ignore the GUESTFISH_PS1)

>From that I see that PS1 is assigned a string in single quotes, and that
several magic backslashes are getting interpolated from within that
string *every time the prompt gets displayed*.  So there is extra magic
going on that doesn't happen in the normal course of command line variables.

So next, I took a look at "man bash" to see what guidance it could give:

PROMPTING
       When executing interactively, bash displays the primary prompt
PS1 when
       it  is  ready  to  read a command, and the secondary prompt PS2
when it
       needs more input to complete  a  command.   Bash  allows  these
prompt
       strings  to  be  customized  by inserting a number of
backslash-escaped
       special characters that are decoded as follows:

...hoo boy, so, inded there is an extra layer of interpolation going on,
and specifically involves backslashes.  There follows a list of about
twenty different characters that can follow the backslash, including:

              \\     a backslash

Now, after that layer of backslashing, there will be another layer
performed on any shell invocation, e.g., from $().  So I tried

PS1='$(pwd | sed -e "s,/,\\\\,g)" '

...which didn't work.  Why?  We've got one special reduction of
backslashes because this is a prompt, so at variable interpolation
(which includes the $()) what's getting evaluated is

pwd | sed -e "s,/,\\,g"

...and then, when it gets to sed, sed will see an argument

s,/,\,g

Aha.  sed is *also* interpreting backslashes, so it complains that the
substitution is unterminated, since the backslashing of the trailing
comm made it part of the substitution string, and then there wasn't the
terminating character.  So what *did* work was:

PS1='$(pwd | sed -e "s,/,\\\\\\,g") '

So: magic prompt interpolations turn it into

$(pwd | sed -e "s,/,\\\,g") '

Shell interpolations turn it into

pwd | sed -e s,/,\\,g

and, finally, sed's interpolation turns the substitution string between
the , delimiters into

\

...and that succeeded.

Why, yes, I frequently write code I warn my employer to erase :-)

Next exercise for the reader:

Don't use sed; instead use the variable expansion glob patterns.


    - Stephen
On 4/19/19 5:33 PM, bick via TriLUG wrote:
> When I first started using Linux a few years ago, I went through
> tutorials on how to change the command prompt.  I changed the colors,
> etc.  I'm just going through this book, because I thought it would be a
> fun refresher.  I don't get a lot of practice with the command line
> tools in my daily use.
> 
> I am really not concerned with changing my prompt to make it look like
> Windows.  I am really just interested to know why what I'm doing isn't
> working for the backslash, when it works to replace the slashes with any
> other character or combination of characters I have tried.
> 
> Thanks again for your time.
> 
> On 4/19/19 3:39 PM, David Both wrote:
>> Why not try something different to learn about changing your command
>> prompt? Here are a couple articles available on Opensource.com. I
>> write for them requently but neither of these articles is one of mine.
>>
>> https://opensource.com/article/17/7/bash-prompt-tips-and-tricks
>>
>> https://opensource.com/article/18/12/linux-toy-bash-prompt
>>
>> Here is an article of mine about Bash command line programming. You
>> might find it useful.
>>
>> https://opensource.com/article/18/11/control-operators-bash-shell
>>
>> There are many more articles there to help you learn the Bash shell.
>> Just search for Bash.
>>
>>
>> On 4/19/19 4:27 PM, Bick via TriLUG wrote:
>>> To be fair, this is not part of an overall strategy of the book to
>>> make things more Windows like.  It is just a one-off example, not
>>> meant to be actually used in practice, and I think the author is
>>> having a bit of fun.
>>>
>>> As for me, I am annoyed that I have spent this much time on the
>>> problem, because I would never want to make the prompt look more like
>>> Windows.  However, it bothers me that it doesn’t work, and as far as
>>> I can tell, none of the bash prompt how-tos I have found online
>>> explain why.  If you have any ideas, or know what documentation I
>>> should be reading to find the answer, I would greatly appreciate it.
>>>
>>>> On Apr 19, 2019, at 3:14 PM, David Both via TriLUG
>>>> <trilug at trilug.org> wrote:
>>>>
>>>> First - kudos to you for trying to learn Linux and the command line.
>>>>
>>>> <rant>
>>>>
>>>> I understand what you are doing and why, but the author of that book
>>>> should never be allowed to write another book with the word Linux in
>>>> it. Ignore that exercise once you have finished it. Never think of
>>>> it again. Then find a better book.
>>>>
>>>> There is a horrible problem with Windows people trying to make Linux
>>>> look and work like Windows. In my articles and books I caution
>>>> against this approach to learning Linux. You will never really learn
>>>> Linux if you try to make it work like Windows. My primary example of
>>>> this is using aliases so the user can type a Windows command that is
>>>> then interpreted by the shell into its Linux equivalent. I will add
>>>> this example to my list at the next opportunity.
>>>>
>>>> What this tells me is that the author is stuck in the Windows world
>>>> and is, probably unconsciously but nonetheless, trying to infect
>>>> readers in the same way. Linux is not Windows, and trying to make it
>>>> so will only impede your efforts to learn Linux.
>>>>
>>>> I can think of a slew of different things to do with the command
>>>> prompt than making it look like Windows.
>>>>
>>>> </rant>
>>>>
>>>> Good luck and keep learning!
>>>>
>>>>
>>>>> On 4/19/19 3:55 PM, Bick via TriLUG wrote:
>>>>> I am reading through a Linux book right now and one of the
>>>>> exercises in the chapter about environment variables is to make the
>>>>> prompt look more Windows like.  Specifically, I am supposed to make
>>>>> the prompt display C:\directory.  I first attempted to use sed to
>>>>> accomplish it like this: PS1='C:$(echo $(pwd) | sed 's:/:\\:g') '. 
>>>>> The result is C:parentDirchildDir.  It does not print slashes.  If
>>>>> I just put the command I am calling directly into the bash prompt,
>>>>> I get the proper output: C:\parentDir\childDir.
>>>>>
>>>>> I thought maybe the problem was that the single slash was being
>>>>> reinterpreted as an escape character when PS1 was being read, so I
>>>>> tried using four slashes (so that two would be present in the PS1
>>>>> string).  Again typing this at the command prompt worked (output
>>>>> was C:\\parentDir\\childDir), but it didn't work as part of
>>>>> assigning it to PS1.
>>>>>
>>>>> I have also tried assigning the commands I want to run to a
>>>>> variable, $NEWPWD, I created in PROMPT_COMMAND.  I then used the
>>>>> variable in the PS1 assignment.  This didn't work either.
>>>>>
>>>>> I have successfully replaced the slashes with letters, numbers, and
>>>>> even an exclamation point (which needed to be escaped by a
>>>>> backslash) using ALL of the above methods.  Any ideas why this
>>>>> doesn't work with backslashes?
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Chris
>>>> -- 
>>>>
>>>> *********************************************************
>>>> David P. Both
>>>> *********************************************************
>>>> The value of any software lies in its usefulness
>>>> not in its price.
>>>>
>>>> — Linus Torvalds
>>>> *********************************************************
>>>>
>>>> -- 
>>>> This message was sent to: bick <bick at bickhaus.net>
>>>> To unsubscribe, send a blank message to trilug-leave at trilug.org from
>>>> that address.
>>>> TriLUG mailing list : https://www.trilug.org/mailman/listinfo/trilug
>>>> Unsubscribe or edit options on the web    :
>>>> https://www.trilug.org/mailman/options/trilug/bick%40bickhaus.net
>>>> Welcome to TriLUG: https://trilug.org/welcome
>>


More information about the TriLUG mailing list