Comments 37
Я однажды заинтересовался возможностями разбора history, в результате получил sudo для всей командной строки, включая пайпы и редиректы:
Использовать так:
Несерьезно, но забавно. И нельзя вставлять в пайп.
proceed_sudo () { sudor_command="`HISTTIMEFORMAT=\"\" history 1 | sed -r -e 's/^.*?sudor//' -e 's/\"/\\\"/g'`" ; sudo sh -c "$sudor_command"; }; alias sudor="proceed_sudo # "
Использовать так:
$ sudor make me a sandwitch > /var/lib/sandwitch
Несерьезно, но забавно. И нельзя вставлять в пайп.
+3
Залез в свои .bash*, нашел кучу старых добрых, но забытых вещей :)
Вот например, итерация по чему-нибудь с прогресс-метками:
И использование:
Пример:
Вот например, итерация по чему-нибудь с прогресс-метками:
finit() { count=$#; current=1; for i in "$@" ; do echo $current $count; echo $i; current=$((current + 1)); done; }
alias fnext='read cur total && echo -n "[$cur/$total] " && read'
И использование:
finit 1 2 3 4 | while fnext item; echo $item ; done
Пример:
$ finit 1 2 3 4 | while fnext item; do echo $item; done
[1/4] 1
[2/4] 2
[3/4] 3
[4/4] 4
+2
Интересно, когда это sed успел научиться нежадными множителями? Небольшой опыт показывает, что
В zsh можно такое устроить переопределяя accept-line widget. Тоже правда выглядит как хак, особенно вместе с функцией, которая засовывает в историю исходный текст, а не то, что будет реально выполнено. Как мне кажется, возможность работы
.*?
ничем не отличается от .*
. Точнее от (.*)?
, за исключением сохранения текста.В zsh можно такое устроить переопределяя accept-line widget. Тоже правда выглядит как хак, особенно вместе с функцией, которая засовывает в историю исходный текст, а не то, что будет реально выполнено. Как мне кажется, возможность работы
echo abc | sudor { read def && echo $def } | read ghi
можно обеспечить в обоих случаях если немного заморочиться. 0
Вставлю свои «5 копеек»:
В таком виде только в zsh возникают «нюансы»: команды «echo a» не существует.
Надёжнее делать:
С использованием eval проблем нет ни в одном из шеллов (ну, насколько мне известно...;)
При использовании команды sudo в скриптах, почти всегда лучше использовать ключ -i: в неинтерактивном режиме, большая часть шеллов не source'ит rc и profile файлы, что может привести к проблемам в работе софта.
Попытаюсь вспомнить ещё чего-нибудь «забавного» и допишу.
a="echo a";
$a
В таком виде только в zsh возникают «нюансы»: команды «echo a» не существует.
Надёжнее делать:
a="echo a";
eval $a
С использованием eval проблем нет ни в одном из шеллов (ну, насколько мне известно...;)
При использовании команды sudo в скриптах, почти всегда лучше использовать ключ -i: в неинтерактивном режиме, большая часть шеллов не source'ит rc и profile файлы, что может привести к проблемам в работе софта.
Попытаюсь вспомнить ещё чего-нибудь «забавного» и допишу.
+1
Полезный маленький трюк:
делают одно и то же. Последнюю переменную можно использовать для всяких mv дополнительно.
Ещё мелкая «полезняшка», экономящая время на длинных именах файлов:
На время отладки можно добавить ключ -x к шабангу:
Эквивалентно set -x.
cd -
cd $OLDPWD
делают одно и то же. Последнюю переменную можно использовать для всяких mv дополнительно.
Ещё мелкая «полезняшка», экономящая время на длинных именах файлов:
mv file{,.bak}
На время отладки можно добавить ключ -x к шабангу:
#!/bin/bash -x
Эквивалентно set -x.
+2
eval стоит использовать с огромной осторожностью. Некоторые любят устроить публичную порку за его использование, дескать это пропасть в безопасности, за такое руки отрубать надо (:
+1
А еще довольно много интересных возможных ошибок собрано тут: mywiki.wooledge.org/BashPitfalls
После прочтения пришлось некоторые скрипты переделать
После прочтения пришлось некоторые скрипты переделать
+1
Помню, как то нужно мне было сделать перебор от 1 до нужного мне числа. Вот тогда, я и познакомился с «граблями» в Bash-е )
Вот пример того, как Bash с аппетитом начнет «кушать» вашу RAM:
Итого, скрипт взял на себя 1831 Mb.
Чуть позже, нашел другой вариант, «полегче»:
Тут уже, почти в 2 раза меньше. Всего 1049 Mb. Но все равно, мне как то, не посебе, когда на такое, уходит столько памяти.
Вот пример того, как Bash с аппетитом начнет «кушать» вашу RAM:
#!/bin/bash
for i in {1..10000000}; do
echo "item: $i";
done
Итого, скрипт взял на себя 1831 Mb.
Чуть позже, нашел другой вариант, «полегче»:
#!/bin/bash
for i in $(seq 10000000); do
echo "item: $i";
done
Тут уже, почти в 2 раза меньше. Всего 1049 Mb. Но все равно, мне как то, не посебе, когда на такое, уходит столько памяти.
+1
UFO just landed and posted this here
Может кому пригодится:
Меняем формат мак адреса с 0000.0000.0000 (cisco like) на 00:00:00:00:00:00:
Меняем формат мак адреса с 0000.0000.0000 (cisco like) на 00:00:00:00:00:00:
echo "0000.0000.0000" |sed -e 'y/./:/' | sed -r 's/([0-9,a-f]{2})([0-9,a-f]{2})/\1:\2/g'
0
Хозяйке на заметку: если надоело выискивать очередной подводный камень шелла, перепишите скрипт на перле.
-1
2й пункт. Да вы что !??!
Проблема subshell'а решается через именованый пайп на раз-два!
$ while read line; do X=$line; done < <(cat /etc/hosts | head)
$ echo $X
# IPv4 and IPv6 localhost aliases
Проблема subshell'а решается через именованый пайп на раз-два!
+1
Башизм же. Я старался обойтись чем-нибудь POSIX совместимым.
0
в 3м пункте лучше отправить в 3-й файловый дескриптор все же, не трогайте stderr :).
0
[[ 2 -eq 3 ]] [[ "test" == "test" ]] [[ $VAR -eq 3 ]]
Поначалу с виду подумал, что это пауэршелльный код, только следующее примечание про Баш всё расставило по местам.
0
насчет строк в test надо аккуратнее — в случае нескольких строк ( а так бывает если вывод команды ) типа
стоит обратить внимание на кавычки вокруг $VAR
А вообще shell скриптинг — это для внимательных к деталям и сахарку в неожиданных местах. Перлисты поймут.
Но регулярные извраты что бы получить простую в классическом ЯП обработку вызывают смешанные чувства.
VAR=`some args`
if [ -n "$VAR" ]; then ...
....
fi
стоит обратить внимание на кавычки вокруг $VAR
А вообще shell скриптинг — это для внимательных к деталям и сахарку в неожиданных местах. Перлисты поймут.
Но регулярные извраты что бы получить простую в классическом ЯП обработку вызывают смешанные чувства.
0
меня тоже смутил второй пункт.
часто достаточно передать файл на вход while, и пайп (и собственно сабшелл) совершенно не нужен.
$ while read; do a=$((a + 1)); done < 1;
дополнение про mkfifo здесь, конечно, также очень полезно.
Расскажите, пожалуйста, в чем разница между [[ ]] и [ ], который test?
Беглый просмотр man bash не помог.
часто достаточно передать файл на вход while, и пайп (и собственно сабшелл) совершенно не нужен.
$ while read; do a=$((a + 1)); done < 1;
дополнение про mkfifo здесь, конечно, также очень полезно.
Расскажите, пожалуйста, в чем разница между [[ ]] и [ ], который test?
Беглый просмотр man bash не помог.
0
Only those users with full accounts are able to leave comments. Log in, please.
Подводные камни shell скриптинга