| Предыдущая версия справа и слеваПредыдущая версияСледующая версия | Предыдущая версия |
| linux:terminal:terminal_tnt_bash [2021/10/26 02:36] – dx | linux:terminal:terminal_tnt_bash [2021/11/22 15:17] (текущий) – dx |
|---|
| | ====== Трюки в консоли: Bash ====== |
| |
| | {{mdi>console?48&align=right}} |
| | |
| | {{tag>bash tnt}} |
| | |
| | ==== /bin/sh^M: bad interpreter ==== |
| | |
| | Ошибка **/bin/sh^M: bad interpreter: No such file or directory** |
| | |
| | TL;DR |
| | |
| | <code bash>sed -i -e 's/\r$//' prikol.sh</code> |
| | |
| | или |
| | |
| | <code bash> |
| | apt install dos2unix |
| | dos2unix prikol.sh |
| | </code> |
| | |
| | К нам в Linux логово прокрался ужасный символ из мира Шиндоус - **^M** — символ возврата каретки |
| | |
| | Из [[https://developer.mozilla.org/ru/docs/Glossary/CRLF|глоссария Мозиллы]] |
| | |
| | CR и LF это управляющие символы [[https://en.wikipedia.org/wiki/Control_character|en]] [[https://ru.wikipedia.org/wiki/Управляющие_символы|ru]] или [[https://en.wikipedia.org/wiki/Bytecode|байт-код]] которые можно использовать для обозначения разрыва строки в текстовых файлах. |
| | |
| | * CR = **Возврат каретки (Carriage Return)** (''\r'', ''0x0D'' в шестнадцатеричной, 13 в десятичной системе счисления) — перемещает курсор в начало строки, не переходя на следующую строку. |
| | * LF = **Перевод строки (Line Feed)** (''\n'', ''0x0A'' в шестнадцатеричной, 10 в десятичной системе счисления — перемещает курсор на следующую строку, не возвращаясь в начало строки. |
| | |
| | CR, за которым сразу следует LF (CRLF, ''\r\n'', или ''0x0D0A'') перемещает курсор на следующую строку и затем перемещает его в начало строки. |
| | |
| | А еще есть утилита **[[https://ru.wikipedia.org/wiki/Tr|tr]]** |
| | |
| | <code bash>cat script.sh | tr -d '\r' > script-fixed.sh</code> |
| | |
| | [[https://www.transl-gunsmoker.ru/2009/03/crlf.html|Перевод поста]] [[http://blogs.msdn.com/oldnewthing/archive/2004/03/18/91899.aspx|Why is the line terminator CR+LF?]] от GunSmoker-а |
| | |
| | Этот протокол восходит к временам телетайпов. |
| | |
| | CR - это аббревиатура для "carriage return" (возврат каретки) - управляющий символ CR возвращал печатающую головку ("carriage") к нулевой колонке без движения бумаги. LF - это аббревиатура для "linefeed" (подача бумаги) - управляющий символ LF сдвигал бумагу на одну строчку без движения каретки. Поэтому, если вы хотели вернуть головку к нулевой колонке (чтобы быть готовым печатать на новой строчке) и сдвинуть бумагу (чтобы печатать на чистом месте), то вам нужны были и CR и LF. |
| | |
| | Если вы посмотрите на большинство интернет протоколов, таких как [[http://www.ietf.org/rfc/rfc0821.txt|RFC 0821 (SMTP)]], [[http://www.ietf.org/rfc/rfc1939.txt|RFC 1939 (POP)]], [[http://www.ietf.org/rfc/rfc2060.txt|RFC 2060 (IMAP)]] или [[http://www.ietf.org/rfc/rfc2616.txt|RFC 2616 (HTTP)]], то вы увидите, что все они указывают пару CR+LF как последовательность, терминирующую строки. Поэтому на самом деле вопрос звучит не как "Почему CP/M, MS-DOS и Win32 используют CR+LF как разделитель строк?", а скорее как "Почему другие люди решили взять другой разделитель, отличный от этих стандартов?". |
| | |
| | Unix принял в качестве разделителя строк простой LF. Если вы посмотрите на [[http://www.opennet.ru/man.shtml?topic=stty&category=1&russian=4|опции stty]], то увидите, что опция onlcr указывает, следует ли менять LF на CR+LF. Если вы установите эту опцию неверно, то вероятнее всего получите текст "лесенкой", где |
| | |
| | <code> |
| | каждая |
| | строка |
| | начинается |
| | </code> |
| | |
| | там, где закончилась предыдущая. Так что даже Unix может требовать CR+LF для разделения строк. Неявный CR перед LF - это изобретение Unix, вероятно с целью экономии одного байта на строчку. |
| | |
| | Unix является "папой" языка C, поэтому стандарт языка C унаследовал это соглашение: разделителем строк в языке является один символ "\n" (что есть LF). Это загружает runtime библиотеки дополнительной работой по преобразованию одиночных символов в разделители строк. |
| | |
| | Также язык C предложил термин "newline" для выражения концепции "общего разделителя строк". Я слышал, что комитет ASCII изменил название символа $0A (LF) на "newline" примерно в 1996, так что уровень запутанности возрос ещё выше. |
| | |
| | ===== Размер истории bash и другие настройки ===== |
| | |
| | <wrap tip>[[http://www.joshstaiger.org/archives/2005/07/bash_profile_vs.html|.bash_profile vs .bashrc]] - важно знать</wrap> |
| | |
| | <wrap tip>[[https://gahcep.github.io/blog/2012/07/28/unix-bash-shell-prompt/|PROMPT_COMMAND]]</wrap> |
| | |
| | Добавляем в ''~/.bashrc'' |
| | |
| | <code bash> |
| | # вывод даты и времени |
| | export HISTTIMEFORMAT="%h %d %H:%M:%S " |
| | |
| | # количество команд, сохраняемых в истории, дефолт 500 |
| | export HISTSIZE=10000 |
| | |
| | # количество строк, сохраняемых в истории, дефолт 500 |
| | export HISTFILESIZE=10000 |
| | |
| | # дополнять историю, а не перезаписывать | xgu.ru/wiki/shopt |
| | shopt -s histappend |
| | |
| | # все строки многострочной команды рассматриваются, как одна |
| | shopt -s cmdhist |
| | |
| | # записывать историю сразу после ввода команды |
| | PROMPT_COMMAND="history -a; $PROMPT_COMMAND" |
| | |
| | # ignorespace - не сохранять строки начинающиеся с пробела |
| | # ignoredups - не сохранять строки, совпадающие с последней выполненной командой |
| | # ignoreboth - использовать обе опции 'ignorespace' и 'ignoredups' |
| | # erasedups - удалять ВСЕ дубликаты команд с истории |
| | # можно комбинировать: |
| | # export HISTCONTROL=ignorespace:erasedups |
| | export HISTCONTROL= ignoreboth |
| | |
| | # не сохранять команды top, history, ping |
| | export HISTIGNORE="top:history:ping" |
| | |
| | # кастомный файл истории команд |
| | export HISTFILE=~/.custom_bash_hist_file |
| | </code> |
| | |
| | [[https://stackoverflow.com/questions/19454837/bash-histsize-vs-histfilesize|HISTSIZE vs. HISTFILESIZE?]] |
| | |
| | ===== Добавить время в history ===== |
| | |
| | Добавляем в ''~/.bashrc'' |
| | |
| | **$ export HISTTIMEFORMAT="%h %d %H:%M:%S "** |
| | |
| | <code> |
| | 1172 Apr 07 14:52:56 ifconfig |
| | 1173 Apr 07 14:53:21 df -h |
| | 1174 Apr 07 14:53:32 free -m |
| | </code> |
| | |
| | или |
| | |
| | **export HISTTIMEFORMAT="%d/%m/%y %T "** |
| | |
| | <code> |
| | 1175 07/04/20 14:54:45 yum check-update |
| | 1176 07/04/20 14:55:00 rm -rf /* |
| | 1177 07/04/20 14:55:10 man backups |
| | </code> |
| | |
| | ===== Debug/verbose для git ===== |
| | |
| | <code>GIT_CURL_VERBOSE=1 GIT_TRACE=1 git pull origin master</code> |
| | |
| | ===== Статистика популярности использования команд на основании history ===== |
| | |
| | <code> |
| | history|awk '{print $2}'|sort|uniq -c|sort -rn|head -20|awk '!max{max=$1;}{r="";i=s=60*$1/max;while(i-->0)r=r"#";printf "%15s %5d %s %s",$2,$1,r,"\n";}' |
| | </code> |
| | |
| | ===== Не сохранять историю в bash ===== |
| | |
| | Как вводить команды и быть увереным, что они не логируются? |
| | |
| | Просто добавь <del>воды</del> пробел |
| | |
| | <code> |
| | [space]ls -la /home |
| | </code> |
| | |
| | Выйти из bash без сохранения истории и оставить предыдущие команды в истории нетронутыми |
| | |
| | <code>unset HISTFILE && exit</code> |
| | |
| | Полностью удалить историю bash и выйти |
| | |
| | <code>history -c && exit</code> |
| | |
| | ===== Не сохранять историю в bash ЧАСТЬ 2 ===== |
| | |
| | Как **полностью** удалить историю bash_history |
| | |
| | <code>cat /dev/null > ~/.bash_history && history -c && exit</code> |
| | |
| | или |
| | |
| | <code>history -c && history -w</code> |
| | |
| | ===== Как вывести полную дату для команды last ===== |
| | |
| | <code>last -F</code> |
| | |
| | Ключ ''-F'' - Print full login and logout times and dates. |
| | |
| | <code>reboot system boot 2.6.32-573.22.1. Thu Jan 26 09:48:36 2017 - Sun May 27 17:39:39 2018 (486+07:51)</code> |
| | |
| | <code>reboot system boot 2.6.32-573.22.1. Thu Jan 26 09:48 - 17:39 (486+07:51)</code> |
| | |
| | === Как очистить историю команд в bash === |
| | |
| | via [[https://bogachev.biz/2014/11/04/Как-очистить-историю-команд-в-Bash|https://bogachev.biz/2014/11/04/Как-очистить-историю-команд-в-Bash]] |
| | |
| | **Полностью удалить историю Bash** |
| | |
| | **-c** - Очистить файл истории\\ |
| | **-w** - Внести команды текущей сессии в файл с историей |
| | |
| | <code>$ history -cw</code> |
| | |
| | **Удалить определенную строку из истории Bash** |
| | |
| | **d** - Удалить строку с указанным номером из истории |
| | |
| | <code>$ history -dw 352</code> |
| | |
| | **Очистить историю команд текущей сессии** |
| | |
| | **-r** - Прочитать файл с текущие историей и добавить его содержимое к списку истории команд |
| | |
| | <code>$ history -r</code> |
| | |
| | **Не сохранять команду в истории Bash** |
| | |
| | Выполнить команду не занося ее в историю Bash: |
| | |
| | <code>$ <пробел>команда</code> |