Мне нужен путь с разделением цветов в PS1. Я пишу эту функцию в .bashrc.
colorize_dir_path() {
#local path=$(echo "$PWD" | perl -pe "s|$HOME|~|")
#local path = "~/project/at-gui/src"
local path=$1
local colored_path = ""
local color_array=(27 130 28 133)
local index=0
IFS='/' read -ra ADDR <<< $path
for i in "${ADDR[@]}"; do
if [ "$i" != "" ]; then
local color=${color_array[$index]}
((index=(index+1)%${#color_array[@]}))
colored_path+ = "\e[48;5;${color}m $i "
fi
done
echo -e "\e[37m${colored_path}➽\e[0m" #白色前景
}
и установите PS1.
PS1 = "$psc1 \D{%F %A %T} $pgap$(colorize_dir_path "\w")\n$psch "
#PS1 = "$psc1 \D{%F %A %T} $pgap$(colorize_dir_path "$PWD")\n$psch "
#PS1 = "$psc1 \D{%F %A %T} $pgap$(colorize_dir_path "$(pwd)")\n$psch "
#PS1 = "$psc1 \D{%F %A %T} $pgap$(bash ~/bin/ps1.bash "\w")\n$psch "
Но \w не может разбиться на массив ADDR, я получил только весь путь. кажется, это не строка. Как это решить? пожалуйста, помогите.
Вы установили для IFS значение /, но строка не содержит косой черты. Какого «раскола» вы ожидали?
Кстати: почему вы объявляете все остальные переменные локальными, а не ADDR или i?
Отдельно echo -e — дурной тон; printf более надежен, поскольку позволяет вам контролировать, какие строки интерполируются, а какие нет. (например, printf '%b%s%b' '\e[37m' "$colored_path" '➽\e[0m' будет обрабатывать escape-последовательности как таковые, потому что %b инструктирует его интерполировать, но без изменения вашего пути, если он содержит буквальную обратную косую черту или что-то в этом роде, потому что %s обрабатывает вещи точно так, как они уже есть).





PS1 = "$psc1 \D{%F %A %T} $pgap$(colorize_dir_path "\w")\n$psch "
Раскрывает все параметры во время назначения, включая подстановку команд. Это означает, что PS1 присвоено постоянное значение и \w не имеет особого значения за пределами PS1; он расширяется вашей оболочкой только при отображении строки приглашения.
Вместо этого попробуйте это, чтобы подстановка команды расширялась только при отображении строки приглашения (обратите внимание на одинарные кавычки):
PS1 = "$psc1 \D{%F %A %T} $pgap"'$(colorize_dir_path "\w")'"\n$psch "
Время оценки/расширения легко проверить самостоятельно:
PS1 = "$(date):\w\$ "
echo "$PS1" # prints: Fr 28 Jun 2024 11:40:44 CEST:\w$
и время, отображаемое в вашей подсказке, является постоянным и никогда не меняется. По сравнению с:
PS1='$(date):\w\$ '
echo "$PS1" # prints: $(date):\w\$
и каждый раз, когда ваша строка запроса отображается, она будет оцениваться, и текущая дата и время будут печататься рядом с вашим текущим рабочим каталогом.
Аналогичный тест:
PS1 = "$(echo '\w'>&2)\$ "
выведет \w в stderr ровно один раз при назначении переменной. Однако
PS1='$(echo "\w">&2)\$ '
печатает путь к вашему текущему рабочему каталогу в stderr каждый раз, когда отображается ваше приглашение.
Спасибо. PS1='$(colorize_dir_path "\w")'действительно работает. PS1 = "$(colorize_dir_path "\w")" не работает. Я прочитал ваше объяснение, но все равно запутался. :(
Я видел ваш комментарий выше. Это означает, что я не могу позволить функции $(colorize_dir_path "\w") расширяться до тех пор, пока PS1 не запустится каждый раз? Сохраните эту часть как целую строку, частично поймите. Спасибо.
Самое странное, что если я использую двойные кавычки, функция colorize_dir_path тоже работает, $path — текущий путь, НО у ADDR был только один элемент.
@eexpress, потому что, если он вызывается вне отрисовки подсказки, аргументу передается буквальная строка \w, а не разрешенный путь.
а) Ваши параметры расширяются, а ваша команда заменяется во время определения переменной, а не при визуализации PS1. Вместо этого вы хотите использовать одинарные кавычки:
PS1='…'. б) укажите свои параметры при раскрытии в) вы уже запускали свой скрипт через shellcheck.net?