Я бы хотел настроить свою оболочку bash очень специфическим способом, настолько конкретным, чтобы я не знал, возможно ли это. В настоящее время моя оболочка выглядит следующим образом:
myname@ubuntu /home/myname:
>>
Где myname - мое имя пользователя. Я настроил оболочку со следующей строкой в ~ / .bashrc
:
PS1='${debian_chroot:+($debian_chroot)}\u@\h `pwd`:\n>> '
Когда я нажимаю Enter, вот что происходит:
myname@ubuntu /home/myname:
>>
myname@ubuntu /home/myname:
>>
Вместо этого я хотел бы, чтобы произошло следующее:
myname@ubuntu /home/myname:
>>
>>
Более того, если я наберу команду, что произойдет, должно быть так:
myname@ubuntu /home/myname:
>> echo hello
hello
myname@ubuntu /home/myname:
>>
Следующего не должно произойти
myname@ubuntu /home/myname:
>>echo hello
hello
>>
Возможно ли это? Если да, то как это сделать?
ОБНОВЛЕНИЕ
Я смог достичь своей цели благодаря ответу ChrisAga.
Вот сценарий
# don't put duplicate lines or lines starting with space in the history.
HISTCONTROL=ignoreboth
customprompt() {
# the current number of lines in bash history:
bash_history_size=$(fc -l -1)
bash_history_size=${bash_history_size%%[^0-9]*}
# set an initial value to the number of lines
# in bash history stored from the last time
# this function was executed. This avoids bugs
# when running the first command in the current
# shell session
if [ -n "$bash_history_lastsize" ]; then
bash_history_lastsize=0
fi
# if the current number of lines in bash history
# is different from the last number of lines, then
# we print the user name and the current directory.
# otherwise, we just print >>
if [ "${bash_history_size}" != "${bash_history_lastsize}" ]; then
PS1='\[\033[01;32m\]\u@\h \[\033[00m\]`pwd`:\n>> '
else
PS1=">> "
fi
# update the last value to the current value
bash_history_lastsize=${bash_history_size}
}
PROMPT_COMMAND=customprompt
На самом деле, существует решение для простого bash!
Единственное ограничение - несовместимость с предотвращением дублирования в команде bash. история. Поэтому, если вы не возражаете против дубликатов в своей истории Bash, вы можете установить следующее в ~ / .bashrc
:
HISTCONTROL=ignorespace
function pprompt {
local hcount=$(fc -l -1)
echo ${hcount}
hcount=${hcount%%[^0-9]*}
if [ "${hcount}" != "${ocount}" ]; then
PS1="\[\e]0;\u@\h: \w\a\]\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w:\[\033[00m\]\n>>"
else
PS1=">>"
fi
ocount=${hcount}
}
PROMPT_COMMAND=pprompt
По умолчанию HISTCONTROL = ignoreboth
, что эквивалентно ignorespace: ignoredups
, поэтому вы должны изменить его.
Функция pprompt
получает последнюю команду в истории и сравнивает ее номер с ранее сохраненным значением. Если вы просто нажмете, введите число не изменится, поэтому, если это число изменилось, мы устанавливаем PS1 в полное приглашение, в противном случае мы устанавливаем его в >>
.
Наконец, PROMPT_COMMAND = pprompt
bash для выполнения pprompt перед выводом основного приглашения ( $ PS1
).
NB1. Если вам не нравится отображать домашний путь как ~
, вы можете заменить \ w на `pwd`.
NB2. Если бы мы могли получить фактический номер команды bash (тот, который мы можем отобразить, используя ! #
в приглашении) вместо номера команды истории, мы бы получили решение, совместимое с дедупликацией истории.
Насколько я знаю, вы не можете сделать это просто с помощью простого удара. Но вместо этого вы должны реализовать свою собственную оболочку практически с нуля (не бойтесь, я сделал это, и для этого требуется менее 30 строк кода).
Вот код (custom_shell.sh):
RED='\033[0;31m' #Definition of some ASCII colors
WHITE='\033[1;37m' #Replace them with whatever color you want
TMP_COMM_BUF="/tmp/custom_shell_buf" #For temporary storage of commands
if [ "$1" == "e" ]
then
printf "${RED}>> ${WHITE}" #When you just pressed enter
else
printf "${RED}$PWD >> ${WHITE} " #After the execution of some command
fi
exec 3<&1 #Custom file descriptor
read -u 3 comm_buf #Read commands from stdin
echo $comm_buf > $TMP_COMM_BUF #Store commands (exec cannot execute multiple commands at once , so we need it)
chmod +x $TMP_COMM_BUF #Make it executable
if ! [ -z "$comm_buf" ]
then
echo custom_shell.sh >> $TMP_COMM_BUF #Recover the prompt after the execution ( It's assumed that the name of the file is custom_shell.sh and it's available in the $PATH )
exec $TMP_COMM_BUF #Execute !!!
else
exec custom_shell.sh e #If nothing specified , then just show ">>"
fi
Ограничения:
Поскольку он не может использовать функцию редактирования строки, присутствующую в bash, вы не можете использовать Ctrl + C
для прерывания или Ctrl + L
для очистки терминала. И нет завершение команды и отсутствие истории оболочки.
Соображения безопасности:
Так как он использует незашифрованный файл ( / tmp / custom_shell_buf
) для хранения команд перед их выполнением, если кто-то просто подделывает их прямо перед фазой исполнения (между строками 16 и 21),