0

I'm trying to make a custom prompt. When I hit enter certain values in the prompt should be updated, but its not getting updated. I tried adding export, like this

export PS1="[$v0][$v1][$v2][$v3]$"

But doesnt get updated. For example in the console i write 0 2 "date -R", the output would be something like this

[Fri, 28 Aug 2020 16:54:00 +0200][][][]$

When i press enter it stays exactly the same, but i want it to be updated. I tried also doing single quotes at the PS1 instead of double quotes, but didn't work.

Heres the full code:

#!/bin/bash

updatedata() {



v=$(awk -v strSearch="$1" '
BEGIN{
    FS=";"
}
{
    gsub(/\r/,"")
    for(i=1;i<=NF;i++){
        if($i==strSearch){ print i
            exit
        }
    }
}
' data.csv)

sum=0
for x in `cut -f $v -d ';' data.csv`
do
    x="${x/$'\r'/}"
    let sum=$sum+$x
done

if [ $pos -eq 0 ]
then
    v0=$sum
elif [ $pos -eq 1 ]
then
    v1=$sum
elif [ $pos -eq 2 ]
then
    v2=$sum
elif [ $pos -eq 3 ]
then
    v3=$sum
fi




         
}
           

       
while [ "$#" -gt 0 ]; do
    pos=$1
    typevar=$2
    stringvar=$3
    case $pos in
      0) v0=$3 ;;
      1) v1=$3 ;;
      2) v2=$3 ;;
      3) v3=$3 ;;
      *) echo "One of the values has invalid position entered, try again"
     
    esac
    case $typevar in
      1) if [  $pos -eq 0 ]
        then
            if [ "$stringvar" != "null" ]
            then
                v0=$stringvar
            else
                v0=""
            fi
        elif [ $pos -eq 1 ]
        then
            if [ "$stringvar" != "null" ]
            then
                v1=$stringvar
            else
                v1=""
            fi
        elif [ $pos -eq 2 ]
        then
            if [ "$stringvar" != "null" ]
            then
                v2=$stringvar
            else
                v2=""
            fi
        elif [ $pos -eq 3 ]
        then
            if [ "$stringvar" != "null" ]
            then
                v3=$stringvar
            else
                v3=""
            fi
        fi ;;
           
       
      2) if [ $pos -eq 0 ]
        then
            v0=`eval $3`
        elif [ $pos -eq 1 ]
        then
            v1=`eval $3`
        elif [ $pos -eq 2 ]
        then
            v2=`eval $3`
        elif [ $pos -eq 3 ]
        then
            v3=`eval $3`
        fi ;;
      3) updatedata $3 ;;
      *) echo "Invalid type of variable, try again"
     
     
     
    esac
    shift
    shift
    shift
   
done

export PS1="[$v0][$v1][$v2][$v3]$"
anonD
  • 47
  • 8
  • 3
    You need to put the value in single quotes. Otherwise the variables are expanded when you assign the variable, not when the prompt is displayed. – Barmar Aug 28 '20 at 15:07
  • so you mean like this? export PS1="['$v0']" – anonD Aug 28 '20 at 15:09
  • What do you mean by `I write 0 2 "date -R"`? How does that get into the `v0`, `v1`, etc. variables? – Barmar Aug 28 '20 at 15:11
  • 0 stands for position of brackets, 2 stands for the type of the input (type 1 is string type 2 is a command(which i use now) and type 3 is a csv column) and the last part is basically whatever you want to input in the brackets, for example "date -R" – anonD Aug 28 '20 at 15:15
  • And how does that get into the variables that you're using in the prompt? – Barmar Aug 28 '20 at 15:19
  • If you enter `0 2 "date -R"`, the shell will try to execute the command `0` with arguments `2` and `date -R`. Have you implemented a command named `0` that populates the variables you are referencing in PS1? – William Pursell Aug 28 '20 at 15:36
  • Maybe its better if I show the full code? I edited my post – anonD Aug 28 '20 at 15:44
  • Take a look at [this post](https://stackoverflow.com/questions/46610384/why-cant-i-use-in-ps1-instead-of-backticks) for some ideas that may help. – Paul Hodges Aug 28 '20 at 17:18

2 Answers2

3

You need to put the prompt in single quotes, not double quotes. Variables inside double quotes are evaluated when you assign to PS1, not when the prompt is printed.

export PS1='[$v0][$v1][$v2][$v3]$'

You can also put command substitutions directly into the prompt, you don't need variables.

export PS1='[$(date -R)][$v1][$v2][$v3]$'
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • I tested it, it worked for me. I did `v0=foo` and my prompt changed to `[foo][][][]$` – Barmar Aug 28 '20 at 15:13
  • That does work, but I mean for example certain commands will change overtime like for example the date -R. Time changes every second. But when I press enter the time stays the same – anonD Aug 28 '20 at 15:17
  • Look at the second version in my answer. That will use the current time. – Barmar Aug 28 '20 at 15:21
  • Yes but how about when I want to use a different position? It needs to depend on number of position that i wrote in command line. So for example I want it in the 3rd bracket, that wont work – anonD Aug 28 '20 at 15:25
  • I don't know what you mean by that. There's nothing that automatically puts what you typed into the prompt. You need to reassign the variables. – Barmar Aug 28 '20 at 15:27
  • If you want to change the third bracket, do `v2=something` – Barmar Aug 28 '20 at 15:27
  • It also doesn't work recursively. You can't put an expression in `v2` and get it to re-evaluate that every time the prompt is shown. If you want it to be evaluated, it needs to be in the `PS1` variable itself. – Barmar Aug 28 '20 at 15:29
0

Using eval is probably a terrible idea, and you can do this without it, but one idea to get you started:

$ PS1='[$v0][$v1][$v2][$v3]\$ '
[][][][]$ v2=test
[][][test][]$ setps() { eval v$1="'$2'"; }
[][][test][]$ setps 2 "$(date)"
[][][Fri Aug 28 15:44:21 GMT 2020][]$
William Pursell
  • 204,365
  • 48
  • 270
  • 300