Получить оцененное значение PS1 или значение командной строки

Вопрос или проблема

Я пытаюсь найти команду, которая вернула бы мне вычисленное значение переменной $PS1 или просто командную строку с текущим путем.

Например:

foo-user@bar-pc:~\bar

Я хотел бы избежать использования чего-то вроде, поскольку pwd не будет обрезать home_dir как ~.

echo "`whoami`@`hostname`:`pwd`"

Это реализация предложения billc.cn:

        $(export PS1; echo exit | sh -i 2>&1)

Конечно, если у вас есть ! в PS1, он будет интерпретироваться как “1”, если только у вас нет какой-то истории сохранения. Имя пользователя, имя хоста, текущий каталог, дата и время и т. д. должны быть в порядке.

Я знаю, что этот вопрос старый, но я наткнулся на него, пока исследовал аналогичную проблему. Так что, если кто-то еще окажется в такой ситуации, вот решение, которое я нашел.

Преобразование параметров Bash

Начиная с версии 4.4, bash включает функцию, называемую преобразование параметров. Она позволяет обрабатывать ваши параметры несколькими различными способами, но здесь нас интересует преобразование строки запроса. Этот тип преобразования активируется добавлением @P к имени переменной внутри фигурных скобок (например: ${myvar@P}).

Используя этот тип преобразования, переменная будет обрабатываться той же логикой, что и при обработке переменной $PS1 перед отображением вашей строки запроса. Это означает, что теперь вы можете получить полностью обработанный вывод вашей строки запроса, просто вызвав переменную так: "${PS1@P}".

Единственная загвоздка здесь в том, что многострочные строки запроса интерпретируют \n странно. Они, похоже, используют возвраты каретки, за которыми следуют пробелы (\x0d\x20), когда не заключены в кавычки, и возвраты каретки, за которыми следуют переводы строки (стили MS: \x0d\x0a), когда заключены в кавычки. Это означает, что курсор возвращается к колонке 1 с возвратом каретки, но если вы не имеете перевода строки, чтобы переместить курсор на строку вниз, то текст для следующей строки просто начинает перезаписывать первую строку.

Например:

bash> PS1='\u@\h:${SHLVL}:\w\nbash> '

alan.bradley@ENCOM1:2:/usr/src/MCP
bash> echo ${PS1}
\u@\h:${SHLVL}:\w\nbash>

alan.bradley@ENCOM1:2:/usr/src/MCP
bash> echo ${PS1@P}
 bash> adley@ENCOM1:2:/usr/src/MCP

alan.bradley@ENCOM1:2:/usr/src/MCP
bash> echo ${PS1@P} | xxd
00000000: 616c 616e 2e62 7261 646c 6579 4045 4e43  alan.bradley@ENC
00000010: 4f4d 313a 323a 2f75 7372 2f73 7263 2f4d  OM1:2:/usr/src/M
00000020: 4350 0d20 6261 7368 3e20 0a              CP. bash> .

alan.bradley@ENCOM1:2:/usr/src/MCP
bash> echo "${PS1@P}"
alan.bradley@ENCOM1:2:/usr/src/MCP
bash>

alan.bradley@ENCOM1:2:/usr/src/MCP
bash> echo "${PS1@P}" | xxd
00000000: 616c 616e 2e62 7261 646c 6579 4045 4e43  alan.bradley@ENC
00000010: 4f4d 313a 323a 2f75 7372 2f73 7263 2f4d  OM1:2:/usr/src/M
00000020: 4350 0d0a 6261 7368 3e20 0a              CP..bash> .

alan.bradley@ENCOM1:2:/usr/src/MCP
bash> |

Так что, если вы хотите отобразить вашу строку запроса, как только вы ее получите, имейте в виду, что вам нужно будет заключить переменную в кавычки, чтобы многострочные строки запроса отображались правильно.

Ответ или решение

Для получения оцененного значения переменной окружения PS1 в оболочке Bash, можно использовать несколько подходов, которые позволяют безопасно извлечь форматированный вывод переменной без необходимости ручного анализа. Одним из наиболее элегантных способов является использование функции трансформации параметров, доступной в Bash начиная с версии 4.4.

Получение оцененного значения переменной PS1

Для получения фактического значения переменной PS1, которое будет отображать текущую рабочую директорию, имя пользователя и имя хоста в формате, установленном в PS1, можно воспользоваться следующей конструкцией:

echo "${PS1@P}"

Как это работает

  • ${PS1@P}: Использование конструкции @P выполняет трансформацию строки, которая позволяет Bash интерпретировать специальные символы (например, \u, \h, \w) так, как это делается при выводе приглашения командной строки.
  • Ваша команда выведет форматированное значение, например: foo-user@bar-pc:~, при условии что PS1 правильно настроен.

Обработка многострочных приглашений

Однако, если ваше приглашение имеет многострочную структуру, нужно учитывать, что интерпретация может привести к неэстетичному выводу:

  • Без кавычек: вы можете наблюдать проблемы с отображением, причем текст может перекрывать друг друга.
  • С кавычками: при использовании двойных кавычек, вы избежите проблем с форматированием (например, ненужные символы возврата каретки).

Пример правильного использования:

# Пример с многострочным приглашением
PS1='\u@\h:\w\n$ '
echo "${PS1@P}"

Альтернативные способы

Если вы не пользуетесь Bash версии 4.4 и выше, вы можете использовать команду для старых версий:

$(export PS1; echo exit | sh -i 2>&1)

Этот метод создает интерактивную оболочку, в которой переменная PS1 будет окрашена, но стоит заметить, что такой подход может привести к неожиданным результатам из-за некоторых символов, таких как !, которые будут интерпретироваться по-другому.

Заключение

Получение значения переменной PS1 в Bash — это полезный трюк для пользователей, желающих динамически отображать свои команды, сохраняя при этом интеграцию с текущей средой. При использовании этих методов вы сможете удобно извлекать отформатированное значение PS1, минимизируя ручные операции и ошибки.

Не забудьте проверить версию вашего Bash с помощью команды bash --version для того, чтобы выбрать наиболее подходящий метод получения значений.

Оцените материал
Добавить комментарий

Капча загружается...