Случайны выбор дневника Раскрыть/свернуть полный список возможностей


Найдено 764 сообщений
Cообщения с меткой

bash - Самое интересное в блогах

Следующие 30  »
rss_rss_hh_new

Щелевая съёмка: реализация на bash (ffmpeg + imagemagick)

Суббота, 08 Мая 2016 г. 00:38 (ссылка)

Не помню что и почему я искал в интернете несколько дней назад, но я наткнулся на интересную статью с необычными фотографиями. А позже на еще одну статью, где описывалась реализация алгоритма создания таких фотографий на python. После прочтения меня заинтересовала эта тема и я решил провести вечера майских праздников с пользой для себя, а именно реализовать алгоритм «конвертирования» видео в щелевое фото. Правда, не на питоне, но подручными средствами на bash'е. Но обо всем по порядку.



Что такое щелевое фото


Вид фотографии, на которой запечатлено не одно событие в один конкретный момент времени, а несколько событий. Это достигается за счет того, что щелевая камера снимает кадры шириной в один пиксель (это и есть «щель») и «склеивает» их в одно фото. Немного запутанно звучит и пока сложно представить, что это такое и как выглядит. Самым доходчивым объяснением для меня был комментарий к одной из вышеупомянутых статей от пользователя Stdit:

image

После этого все становится понятным.



Пример для наглядности:

image



Алгоритм построения щелевой фотографии



  1. Разложить видео на множество изображений.

  2. Обрезать каждое полученное изображение по ширине в один пиксель с заданным смещением (щелью).

  3. Собрать полученное множество изображений в одно.



Звучит нестрашно и просто.



Дано



  • Камера Xiaomi Yi

  • Желание разобраться и сделать несколько необычных фото

  • Пару вечеров свободного времени





Решение


Первое и самое простое, что приходит на ум, это написать bash скрипт, который будет обрабатывать видео и фото в соответствии с описанными шагами алгоритма. Для реализации задуманного мне понадобился ffmpeg и imagemagick. В упрощенном виде на псевдо bash скрипт выглядит так:

ffmpeg -i videoFile frame-%d.png

for ((i = 1; i <= framesCount; i++));
do
convert -crop 1xframeHeight+slitShift+0 frame-$i.png slit-$i.png
done

montage slit-%d.png[1-framesCount] -tile framesCountx1 -geometry +0+0 outputImage




Разберемся что здесь происходит



  • Во-первых, с помощью утилиты ffmpeg разбиваем видео на множество изображений вида frame-0.png...frame-n.png.

  • Во-вторых, с помощью утилиты convert из пакета imagemagick обрезаем каждое полученное изображение (ключ -crop) следующим образом: ширина == 1px, высота == высоте изображения. Так же указываем смещение щели по горизонтали. Сохраняем в файлы вида slit-0.png...slit-n.png.

  • В-третьих, с помощью утилиты montage из пакета imagemagick собираем полученные изображения в одно фото. Ключ -tile указывает на то, что все фото нужно собрать в одно по шаблону «framesCount по горизонтали и 1 по вертикали», то есть собрать множество изображений в один ряд.





Результат


За пару вечеров был написан скрипт, которому на вход подаем видео файл, а на выходе получаем фотографию. В теории на вход можно подавать видео в любом формате, который поддерживает ffmpeg. Выходной файл можно получить в тех форматах, которые поддерживает imagemagick.



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

./slitcamera.sh --input=test.avi --output=test.png --slit-shift=100



где input — видео файл для обработки, output — название результирующего файла, slit-shift — смещение щели по горизонтали.



Первым делом для быстрого тестирования я не стал снимать видео на камеру, а скачал первое попавшееся видео с youtube и «скормил» его скрипту. Вот что из этого вышло:





На следующий день с собой на прогулку я взял свою Xiaomi Yi и снял несколько видео. Вот что из этого вышло:



Родное Азовское море (фото сделано из видео разрешением в 1920x1080 пикселей и продолжительностью в 31 секунду, 60к/с)









А эти фото собраны из видео разрешением в 1280x720 пикселей и продолжительностью в 16 секунд, 120к/с. Обратите внимание на фон второго фото. Он не статичен. На фоне было движущееся колесо обозрения.



Посмотреть и скачать скрипт можно в моем репозитории на GitHub. Предложения, критика и пулреквесты только приветствуются.



Original source: habrahabr.ru.

https://habrahabr.ru/post/283122/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Мой опыт настройки окружения для Web-разработки

Четверг, 05 Мая 2016 г. 20:19 (ссылка)

Речь пойдет не о настройке денвера и не о том, как поставить LAMP-стек. Я решил рассказать о том, какое мы в своей команде используем окружение для разработки. Мы разрабатываем Web-сервисы и ERP-системы, но всё это, в сущности, ничто иное, как сайты. Просто сложные внутри и порой не такие красивые снаружи.



Сразу хочу сказать, что я не претендую на описание идеального окружения для Web-разработки. С удовольствием послушаю критику, приглашаю всех поделиться своими подходами в комментариях. В общем, поехали.





Подождите, а чем плох денвер?



Основной недостаток денвера состоит в том, что проекты в production не работают на денвере. А значит мы не можем гарантировать, что тщательно отлаженные на компьютере разработчика скрипты не начнут «чудить», когда попадут в production. В production проекты обычно работают в Linux (в нашем случае это CentOS или Amazon Linux). Кроме того, работая на денвере, мы не сможем использовать различные утилиты и средства, которые нам нужны в проекте (например, catdoc, поиск sphinx и многое другое).



Ок, но ведь не все готовы работать в Linux!



Разрабатывать прямо в Linux, конечно круто, но правда жизни такова, что большинство разработчиков пользуются Windows в качестве основной OC на компьютере. Поэтому дальше я опишу наш рецепт, как работая в Windows, разрабатывать сайты в Linux.



Мы используем CentOS 7, но думаю, без существенных изменений все будет работать и на других дистрибутивах.



Создаем образ виртуальной машины



Ок. Первое, что нужно сделать — это поставить на компьютер гипервизор (VmWare Workstation, Oracle VirtualBox или может какой-то другой по вкусу). Мы используем VmWare. После этого создаем виртуальную машину и разворачиваем в ней тот образ Linux, на котором будут работать наши проекты в production. Устанавливаем Web-сервер, СУБД, в общем все, что нам нужно для запуска проекта. Кстати, если есть образ виртуалки для production, то еще лучше — можно его и взять за основу.



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



Сетевая папка



Первый вопрос, который у нас встал на этом этапе. Нам теперь что, скрипты проекта через putty редактировать?! И очевидное решение, которое мы нашли, было удивительно простым. В Windows-машине нужно завести отдельную папку, в которой будут лежать все наши проекты. Эту папку нужно расшарить для доступа по сети и примонтировать в корневую директорию, с которой работает Web-сервер.



Чтобы все это работало надежнее, я написал скриптик cifs_mount.sh, буквально из 2 строчек кода, который поставил в виртуалке на запуск раз в 5 минут.

#!/bin/sh
if ! mount -t cifs | grep -q `cat /root/file_server`
then mount -t cifs -o uid=apache,gid=apache,iocharset=utf8,noserverino,credentials=/root/.cifscreds `cat /root/file_server` /var/www
fi


Скрипт проверяет, не отвалилась ли шара (простите мой французский). И если отвалилась, обратно ее монтирует.



Файл /root/file_server

//192.168.0.2/Projects



Файл /root/.cifscreds

username=developvm

password=secretpass





В целом, это решение работает надежно, как утюг.



Но тем не менее есть один небольшой нюанс.
Иногда бывает, что при копировании больших файлов, вылетает ошибка cifs. Как правило, это связано с тем, что в Windows не хватает выделенной памяти для шары. Вылеты происходят из-за того, что Win7 настроена по умолчанию на экономию памяти для сетевых подключений, в частности, размер выделяемого для этих целей пула памяти ограничен, и если для обработки файла требуется больше, то Win7 шлет Linux фатальную ошибку интерфейса и CIFS падает.



Также бывает наблюдаются периодические проблемы с неполной загрузкой страниц (не подгружаются CSS или вообще ошибки при попытке Apache прочитать файл). Причем это возникает время от времени без какой-либо системы.

При этом в логе ошибок Apache следующие ошибки:

[Tue Oct 20 10:44:28.417589 2015] [core:crit] [pid 9632] (5)Input/output error: [client 192.168.1.5:60666] AH00529: /var/www/project/.htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable and that '/var/www/project/' is executable, referer: http://192.168.1.102/script.php

[Tue Oct 20 10:44:28.418762 2015] [core:error] [pid 9555] (5)Input/output error: [client 192.168.1.5:60670] AH00132: file permissions deny server access: /var/www/project/css/main/layout-main.css, referer: http://192.168.1.102/script.php





Чтобы ликвидировать все эти проблемы разом, нужно подредактировать реестр Win7, а именно:

1. У HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\LargeSystemCache установить значение 1

2. У HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters\size установить значение 3



После этого перезапустить LanmanServer. “net stop srv”/“net start srv”. На виртуалке перемонтировать шару.





И еще один нюанс касается опции noserverino
В свое время он породил этот мой вопрос на stackoverflow. Если кратко, эта опция нужна. Подробнее можно почитать по ссылке.





Не стоит пугаться этих нюансов! Они накопились у нас почти за 10 лет разработки с использованием этого подхода.



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



Подпапки для проектов.



А что если у нас больше 1 проекта. Каждый раз поднимать новую виртуалку!? Нам на помощь приходят виртуальные хосты. Придется опять написать небольшой скриптик flush_vhosts.sh (сугубо для удобства работы).

#!/bin/sh

rm /etc/httpd/conf.d/vhosts/*

rm /etc/hosts
echo '127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4' >> /etc/hosts
echo '::1 localhost localhost.localdomain localhost6 localhost6.localdomain6' >> /etc/hosts

for D in `find /var/www -maxdepth 1 -mindepth 1 -type d -printf '%f\n'`
do
echo '' >> /etc/httpd/conf.d/vhosts/$D.conf
echo "ServerName $D.wde" >> /etc/httpd/conf.d/vhosts/$D.conf
echo "ServerAlias *.$D.wde" >> /etc/httpd/conf.d/vhosts/$D.conf
echo "DocumentRoot /var/www/$D" >> /etc/httpd/conf.d/vhosts/$D.conf
if [[ $D == *"bitrix"* ]]
then
echo 'php_admin_value mbstring.func_overload 2' >> /etc/httpd/conf.d/vhosts/$D.conf
echo 'php_admin_value mbstring.internal_encoding UTF-8' >> /etc/httpd/conf.d/vhosts/$D.conf
echo 'php_admin_value max_input_vars 10001' >> /etc/httpd/conf.d/vhosts/$D.conf
echo 'php_admin_value pcre.recursion_limit 1000' >> /etc/httpd/conf.d/vhosts/$D.conf
fi
echo "
" >> /etc/httpd/conf.d/vhosts/$D.conf
echo "127.0.0.1 $D.wde" >> /etc/hosts
done

systemctl restart httpd.service


Вот что он делает:

1. Очищает конфигурацию виртуальных хостов.

2. Очищает /etc/hosts.

3. Дальше он проходится по всем подкаталогам нашей примонтированной папки и создает для каждого каталога новый виртуальный хост Apache. Если в названии каталога находится страшное слово bitrix, то он добавляет в конфиг виртуального хоста несколько специфических настроек для этой замечательной CMS. Добавляет в /etc/hosts новые записи для созданных виртуальных хостов.

4. Перезапускает Apache.



Мы использует в адресах проектов для разработки условный домен первого уровня wde (web developer environment). Можно использовать local или кому что нравится. У нас разрабатываемые проекты доступны по адресам project1.wde, project2.wde и так далее. При этом виртуальные хосты создаются с директивой ServerAlias *.your-folder-name.wde, то есть все поддомены будут также обрабатываться созданным для папки виртуальным хостом.



Таким образом, если нам нужно начать работу над новым проектом, достаточно создать новую папку в общей папке проектов. Выполнить скрипт flush_vhosts.sh. А в Windows прописать адрес для нового проекта в файле C:\Windows\System32\drivers\etc\host.

192.168.1.166 wde

192.168.1.166 site1.wde

192.168.1.166 site2.wde

...и т.д.



Звездочки файл hosts к великому сожалению, не поддерживает. Надо прописывать каждый адрес, с которым будем работать. Вместо 192.168.1.166 нужно указать ip, который вы присвоили виртуальной машине. После этого соответствующий проект будет открываться в браузере по адресам site1.wde или site2.wde и так далее.



Для удобства, если вы пользуетесь, phpMyAdmin, его можно настроить дефолтным хостом. Тогда при обращении по любому адресу, когда Apache не будет находить соответствующую папку проекта, он будет открывать phpMyAdmin. Главное не забыть прописать этот адрес (например, просто wde) в файле hosts в Windows.



Организация загрузочного меню


Чтобы было совсем удобно. И не приходилось новым членам команды объяснять, как обновить конфигурацию виртуальных хостов, настроить сетевую папку и т.д. Я написал еще несколько скриптов для вывода и запуска частых действий через меню. В них нет ничего сверхестественного, прикладываю — может быть кому-то тоже пригодятся.



Собственно скрипт, выводящий меню. Его нужно прописать в файле .bash_profile домашней директории пользователя, под которым мы входим на виртуалку. Для виртуалки, на которой ведется разработка, я считаю можно входить под root, соответственно добавляем в файл /root/.bash_profile строчку ./menu.sh. Теперь сразу после входа в систему будет запускаться наше меню. При необходимости из него всего можно выйти, нажав Ctrl+C.



menu.sh
#!/bin/sh
SCRIPT_DIR=`dirname $0`
source $SCRIPT_DIR/utils.sh

#menu actions
act_net () {
nmtui ;
}

act_folder () {
$SCRIPT_DIR/mount_cfg.sh ;
}

act_flushvhosts () {
$SCRIPT_DIR/flush_vhosts.sh ;
}

act_reboot () {
read -p "System is going to reboot, are u sure? (y/N) " key ;
if [ $key = "y" ]; then
systemctl reboot ;
exit
fi
key=
}

act_shutdown () {
read -p "System is going down, are u sure? (y/N) " key ;
if [ $key = "y" ]; then
systemctl halt ;
exit
fi
key=
}

themenu () {
clear
server_uptime
mnt_detect
echo "===================================================================="
echo "======================= WELCOME to CENTOS WDE!!! ==================="
echo "===================================================================="
echo "======================== wish you happy coding ====================="
echo "===================================================================="
echo -e "System time: "$curtime"\tUptime:"$uptime;
echo ;
echo -e "Mounted folder: "$MNT;
echo ;
echo "=========================== network info ==========================="
echo "`ifconfig -a`"
echo ;
echo `grep nameserver /etc/resolv.conf`
echo ;
echo "`route -n`"
echo ;
echo "====================== current vhosts configs ======================"
echo "`ls -1 /etc/httpd/conf.d/vhosts/`"
echo ;
echo "===================================================================="
echo "========================= Available actions: ======================="
echo -e "\t\tConfigure ${FG_UN}net${NORM}"
echo -e "\t\tConfigure mounted ${FG_UN}folder${NORM}";
echo -e "\t\t${FG_UN}Flush${NORM} virtual hosts";
echo -e "\t\t${FG_UN}Reboot${NORM}";
echo -e "\t\t${FG_UN}Shutdown${NORM}";

echo
echo "Type underlined chars(lowercase) and press ENTER or just ENTER to refresh";
echo "Type Ctrl+C to exit to shell";
echo "====================================================================";
}

while true
do
themenu
read answer
case $answer in
"net") act_net;;
"folder") act_folder;;
"flush") act_flushvhosts;;
"reboot") act_reboot;;
"shutdown") act_shutdown;;
*) echo 'No action found! Refreshing...'; sleep 1; continue;;
esac
done




utils.sh - содержит функции и переменные, используемые в других скриптах
#!/bin/sh
set -o pipefail
mnt_dir="/var/www"

if [ "$interactive" != 'no' ]; then
#cursor movements
CU_RIGHT=$(tput hpa $(tput cols))$(tput cub 7)
#background colors
BG_BLACK=$(tput setab 1)
BG_RED=$(tput setab 1)
BG_GREEN=$(tput setab 2)
BG_YELLOW=$(tput setab 3)
BG_BLUE=$(tput setab 4)
BG_PURPLE=$(tput setab 5)
BG_CYAN=$(tput setab 6)
BG_WHITE=$(tput setab 7)
#foreground colors
FG_RED=$(tput setaf 1)
FG_GREEN=$(tput setaf 2)
FG_YELLOW=$(tput setaf 3)
FG_BLUE=$(tput setaf 4)
FG_PURPLE=$(tput setaf 5)
FG_CYAN=$(tput setaf 6)
FG_WHITE=$(tput setaf 7)
#text-decoration
FG_BOLD=$(tput bold)
FG_HB=$(tput dim)
FG_UN=$(tput smul)
FG_REVERSE=$(tput rev)
#back to defaults
NORM=$(tput sgr0)
fi

#functions to display progress
dots () {
if [ "$interactive" != 'no' ]; then
while true; do
echo -n "."; sleep 0.5
done
fi
}
estart(){
if [ "$interactive" != 'no' ]; then
echo -n "$1"
dots &
dots_pid=$!
fi
}
efinish(){
estatus=$?
if [ "$interactive" != 'no' ]; then
if [ "$estatus" -eq 0 ];then
echo "[ ${FG_GREEN}OK${NORM} ]"
else
echo "[ ${FG_RED}FAIL${NORM} ]"
fi
kill $dots_pid
wait $dots_pid 2>/dev/null
fi
}


#detect server uptime
server_uptime () {
uptime=$(uptime)
uptime=${uptime%%.*}
s=$(( uptime%60 ))
m=$(( uptime/60%60 ))
h=$(( uptime/60/60%24 ))
d=$(( uptime/60/60/24 ))
uptime=$d'd '$h'h '$m'm '$s's '
curtime=$(date +'%Y-%m-%d %H:%M:%S')
}

#detect cifs mount
mnt_detect () {
MNT=$(mount -l | grep $mnt_dir)
if [ ! -z "$MNT" ]; then
MNT=$FG_GREEN$MNT$NORM
else
MNT=$FG_RED"error(not found)"$NORM
fi
}




mount_cfg.sh - настройка параметров сетевой папки
#!/bin/sh
SCRIPT_DIR=`dirname $0`
source $SCRIPT_DIR/utils.sh

clear
echo "========================================="
echo " Mounted folder configuration"
echo " (/var/www)"
echo "========================================="
echo

old_address=$(cat /root/file_server)
old_username=$(grep 'username=' /root/.cifscreds | awk -F '=' '{ print $2 }')
old_password=$(grep 'password=' /root/.cifscreds | awk -F '=' '{ print $2 }')

echo "Type new value and press ENTER or just press ENTER to leave current value.";
echo ;
read -p "Address of fileserver, type like //ip/folder (current value $FG_YELLOW$old_address$NORM): " address ;
read -p "Username (current value $FG_YELLOW$old_username$NORM): " username ;
read -p "Password (current value $FG_YELLOW$old_password$NORM): " password ;

if [ -z "$address" ]; then
address=$old_address; fi
if [ -z "$username" ]; then
username=$old_username; fi
if [ -z "$password" ]; then
password=$old_password; fi

echo "======================================="
echo " New parameters"
echo "======================================="
echo -e "IP address of fileserver: "$address
echo -e "Username: "$username
echo -e "Password: "$password
echo "======================================="
echo
read -p "Save changes? (y/N) " key ;

if [ $key == "Y" -o $key == "y" ]; then
echo "username=$username
password=$password" > /root/.cifscreds
echo "$address" > /root/file_server
estart "Unmounting..."
umount /var/www
efinish
estart "Mounting..."
/root/cifs_mount.sh
efinish
echo ;
read -p "Done. Press any key" key ;
else
echo ;
read -p "Nothing was changed. Press any key" key ;
fi






Система контроля версий



Дальше остается настроить любимую систему контроля версий. Можно пользоваться desktop-приложением для Windows, можно работать через командную строку в putty прямо на нашей виртуальной машине. Кому, как удобнее.



PS. Кстати, одно из величайших открытий для меня было, что можно поставить git или svn непосредственно на production сервере. Когда я в свое время это понял, это ощущение было сравнимо, наверное, с тем чувством, которое испытал Архимед, когда сел в ванную. Ведь больше не надо мучиться с синхронизацией файлов по ftp\sftp, достаточно ввести svn up или git pull origin master!



Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/282884/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

HDD посвящается: усмиряем приложение, прожорливое на дисковое время

Понедельник, 02 Мая 2016 г. 10:35 (ссылка)

Корень всех зол



Долгое время у меня была проблема — система очень сильно тормозила после старта. У меня ноутбук с жёстким диском (HDD) и Ubuntu 14.04.

Как выяснилось, причина крылась в одной лишь программе — демоне Dropbox. Dropbox — это онлайновое файловое хранилище, а его демон — программка, синхронизирующая файлы, расположенные в определённой папке, с онлайн-хранилищем. На старте демон начинает считывать свой кэш. У меня он занимает не одну сотню мегабайт, а удалять его вручную не стоит — есть вероятность потерять данные. Учитывая, что у меня жёсткий диск — устройство с механическими частями — демон начинал потреблять время доступа к нему настолько, что пользоваться компьютером и запускать приложения становилось малореально, пока он не прогрузится. Убрать его из автозапуска и запускать вручную? Неприятное решение, у меня и так есть вещи, которые я на старте вынужден запускать сам (например, iotop, он без прав суперпользователя не запускается). Нужно было найти способ сделать приложение менее прожорливым именно на диск.



ionice нам в помощь. Или нет?



Первое, о чём я услышал по этой теме, была утилитка ionice. Она позволяет изменять приоритет доступа к диску для заданного процесса. Согласно мануалу, существуют три класса приоритетности ввода/вывода. Меня интересовал idle, поскольку он, как я понял из описания, нейтрализует прожорливость приложения, пропуская всегда вперёд него процессы других классов приоритета. Казалось, дело в шляпе, и всё, что надо сделать, это:
ionice -c3 -p $(pgrep dropbox)


Сделано. Эффекта — ноль. Как же так? Ладно, роем дальше.



Scheduler'ы, или «я ничего не понял, но звучит круто»



Как выяснилось, по умолчанию ionice на моей системе вообще не функционирует, поскольку должен быть включён планировщик CFQ. А по умолчанию в новых Убунтах включён планировщик deadline. Не стану вдаваться в подробности, чем они отличаются, ибо сам не до конца въехал. В общем, читаю краткое пояснение по этому делу, а потом меняю планировщик командой (вернее, я добавил эту команду в /etc/rc.local, чтобы планировщик GFQ выставлялся на старте автоматически):
echo cfq > /sys/block/sda/queue/scheduler


Заметка
Кстати, в разделе «замечания» мануала отмечено, что поддержка классов и приоритетов работает на CFQ. Но поскольку до туда всё равно никто не дочитывает… XD



Что-то в системе слегка изменилось. Индикатор load при старте системы стал подниматься выше 11, а процессорная нагрузка стала состоять по большей части из wait. Не уверен, что это всё значит в долгосрочной перспективе, но проблема осталась — переключение на CFQ и последующее применение ionice на процесс dropbox на производительность системы на старте никакого заметного эффекта не произвело: ни положительного, ни отрицательного.



Ну кто столько потоков запускает?! О специфике демона Dropbox.



Я уж было разочаровался, но тут я заметил, что в top показан только один процесс dropbox, а iotop показывает несколько. И кстати, почему в top колонка идентификаторов процессов называется PID, а в iotop — TID? В чём разница между ними? Ответ быстро нашёлся. В моём же случае самое важное открытие: демон Dropbox для своих дел запускает несколько потоков. Много потоков. Выяснилось, что не один десяток. И диск начинают читать иногда по нескольку одновременно. Так вот откуда такие тормоза! А ionice не работал потому, что, присвоив класс приоритета основному процессу, он не передаёт этот класс приоритета дочерним потокам. Поэтому они как были со стандартным классом приоритета, так с ним и остались.

Что ж, как говорят британцы, будем применять bodging. По-нашему, «костыли». Сделаем скриптик, который будет засекать процесс dropbox и все его дочерние потоки, брать их идентификаторы (PID или TID, в данном случае ionice'у это изофаллично до лампочки без особой разницы), и присваивать всем класс idle время от времени (на случай, если dropbox убивает часть дочерних потоков и/или создаёт новые).

#!/bin/bash

while true
do
#собираем список дочерних потоков
TIDS=( $(ps -L --pid $(pgrep -x dropbox) -o tid=) )

for i in "${TIDS[@]}"
do
echo $i
#присваиваем приоритет idle
ionice -c3 -p $i
done

sleep 5

done


Добавляем в автозапуск, перезагружаемся.

И всё заработало почти как будто демона Dropbox вообще нету. Эврика!



Итоги

Таким образом можно работать с любым процессом, потребляющим много дискового времени. Достаточно задать приоритет с помощью ionice и не забывать о подводных камнях, в частности:




  • следить, не запускает ли процесс прожорливые дочерние потоки

  • иметь в виду, что на некоторых системах планировщик ввода/вывода по умолчанию — не CFQ (который поддерживает классы и приоритеты)





Какие ещё вещи следует учитывать? Расскажите о своём опыте в комментариях.



Original source: habrahabr.ru.

https://habrahabr.ru/post/282828/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Не подлежит забвению

Воскресенье, 01 Мая 2016 г. 12:14 (ссылка)

Вы не находите странным черту освистывать нечто до появления некого более функционального аналога оного и проявлять к этому нечто интерес после? На протяжении всего своего существования командная оболочка Windows неоднократно подвергалась жесткой критике, дескать, ее функциональность оставляет желать лучшего, что, казалось бы, должно было сойти на нет с появлением PowerShell, призванного устранить недочеты первой и упростить жизнь разработчикам и системным администраторам. Нет, PowerShell снискал должную популярность, но появился интерес и к самой командной строке особенно после того, как «селекционерами» были открыты способы запускать командные сценарии как WS[H|F] и HTA. Собственные эксперименты и наблюдения показали, что этим дело не ограничивается.



Некоторые символы в cmd наделены особой логикой, например, двоеточие в начале команды означает метку, а потому если командный сценарий состоит из единственной строки :label или даже одного двоеточия, интерпретатор просто ее проигнорирует; если после двоеточия стоит один из знаков перенаправления потока, сути это также не изменит — интерпретатор по-прежнему будет считать данную строку меткой, что в общем-то логично. Вообще, изменяя порядок использования некоторых спецсимволов командной строки, можно добиться любопытных побочных эффектов, таких как, скажем, запуск PHP кода в виде командного сценария:



:


Или то же, но — bash:



:<nul bash "%~f0" %*
echo:End
exit /b
EOF
for i in $@;do echo $i;done


Конечно же при этом обыгрываются особенности самих вызываемых интерпретаторов, но основная суть в том, что такое вообще возможно. Возможен также и запуск сценариев Perl, Ruby или Python как командных сценариев в виду наличия у перечисленных интерпретаторов ключа -x, заставляющий последние игнорировать первую строку передаваемого на исполнение кода. Строго говоря, данное утверждение справедливо для Python, а вот Perl и Ruby с данным ключом будут игнорировать все до тех пор, пока не встретят шебанги #!perl и #!ruby соответственно.



Perl:

@echo off
echo:Start
2>nul perl -x "%~f0" %*
echo:End
exit /b
#!perl
foreach my $i (@ARGV) {print $i, "\n";}


Ruby:

@echo off
echo:Start
2>nul ruby -x "%~f0" %*
echo:End
exit /b
#!ruby
ARGV.each do |i| puts i;end


Python:

@echo off&echo:Start&python3.4m -x "%~f0" %*&echo:End&exit /b
from sys import argv
for i in range(1, len(argv)): print(i)


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



Original source: habrahabr.ru.

https://habrahabr.ru/post/282816/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[Перевод] В международный день пингвина медитативное видео и рассказ про Ubuntu и Bash в Windows 10 от Скотта Хансельмана

Понедельник, 25 Апреля 2016 г. 14:09 (ссылка)

Привет!



Скотт Хансельман — известный активист Microsoft, много пишущий о том, как использовать Open Source и Microsoft. Ниже находится перевод его последней статьи по поводу известной новости по теме Ubuntu и Bash в Windows 10. А еще — сегодня 25 апреля, озаглавленный глобально-важным международным днем пингвинов, поэтому призываем вас почаще посещать пингвинов, а также, конечно, заходить на наш постоянно обновляющийся сайт про Open Source и Microsoft. Если же вам хочется отвлечься в этот прекрасный рабочий день, то прикладываем специальное видео, посмотрев которое, можно будет узнать о пингвинах все.















Раньше приглашение в виде символа $ для пользователей Windows, в том числе для меня, означало «проходите мимо».

Я искал такое приглашение







или такое







Конечно, нужные приглашения встречались не всегда. Но сегодня, в первый день конференции **BUILD**, Кевин Галло (*Kevin Gallo*) рассказал в своем докладе, что теперь разработчики смогут выполнять «**Bash в Ubuntu на Windows**». Эта функция включена в юбилейное обновление Windows 10 (выходит в ближайшее время). Она позволяет выполнять в Windows сценарии оболочки и утилиты командной строки Linux без каких-либо модификаций.



Если вы включите режим разработчика в настройках Windows, добавите эту функцию и запустите сценарий bash, то система предложит загрузить Ubuntu на Windows от Canonical через Магазин Windows:







Этот механизм работает в 64-разрядной Windows и не применяет виртуальные машины. Для чего Bash в Windows может пригодиться разработчикам?

Раньше, когда требовалось запустить Bash в Windows, можно было использовать несколько вариантов.



— Cygwin — утилиты командной строки GNU, скомпилированные для 32-разрядной ОС и отлично интегрированные с Windows. Но это не Linux.

— HyperV и Ubuntu — запуск отдельной виртуальной машины Linux (с выделением X гигабайт ОЗУ и Y гигабайт места на жестком диске) и удаленное подключение к ней (RDP, VNC, ssh).

— Docker также позволяет выполнять контейнер Linux в виртуальной машине HyperV



Запуск bash в Windows — именно этого раньше не хватало. С точки зрения пользователя механизм работает как Linux, поскольку выполняет настоящие бинарные файлы Linux. Просто нажмите клавишу Windows и введите «bash».

После настройки введите «apt-get update» и скачайте несколько пакетов для разработчиков. Мне были нужны Redis и Emacs. Чтобы установить emacs, я запустил команду «apt-get install emacs23». Обратите внимание: это настоящий emacs из репозитория Ubuntu.







Разумеется, я не представляю, как выйти из emacs, поэтому просто закрыл окно. ;)



Обратите внимание: механизм не предназначен для запуска серверов или серверных нагрузок Linux. Этот выпуск ориентирован на разработчиков, которых интересует (или которым необходимо) использование инструментов Linux в рабочем процессе, и снимает это серьезное ограничение. Здесь я установил **Redis с помощью apt-get** и получил возможность выполнять его в изолированном режиме.







Я запускаю Redis в bash и создаю приложения ASP.NET в Visual Studio, использующей кеш Redis. С помощью **Azure Redis Cache** я затем разверну решение в Azure — вполне привычное дело для меня.

Взгляните, каким целостным выглядит теперь мое меню «Пуск»!







В ближайшие недели в блоге [http://blogs.msdn.microsoft.com/commandline](http://blogs.msdn.microsoft.com/commandline) будут опубликованы технические подробности. Кроме того, вас ждут грандиозные обновления базовой консоли, которые улучшат поддержку кодов консоли, ANSI, VT100 и многое другое. Это ранняя версия возможностей, предназначенных для разработчиков, и команда ждет ваших отзывов и комментариев. Функция «Ubuntu в Windows» будет доступна разработчикам в одной из ближайших сборок Windows 10. Изначально некоторые возможности не будут работать так, как задумано, но мы надеемся, что вам будет интересно познакомиться с ними и выяснить, как Ubuntu в Windows вписывается в ваш процесс разработки!









Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/282399/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[Из песочницы] Бесплатный мониторинг CRC ошибок

Вторник, 12 Апреля 2016 г. 11:58 (ссылка)

image



Нередко на сети хранения данных возникают такие неприятные вещи, как рост числа ошибок на портах и увеличение уровня затухания сигнала на sfp модулях. Принимая во внимание высокий уровень надежности SAN инфраструктуры, состоящей из двух и более фабрик, вероятность возникновения аварийной ситуации не так велика, но наложение негативных факторов может привести к потере данных или деградации производительности. К примеру, представьте себе ситуацию: на одной из фабрик проводится обновление FOS, все работает через вторую фабрику, а на ней между коммутатором к которому подключен дисковый массив и коммутатором к которому подключены серверы начинают быстро расти CRC ошибки на одном из транковых портов. Или еще хуже, пропадает линк из-за понижения уровня сигнала, вызванного повышением температуры SFP модуля, которая в свою очередь возросла из-за повысившейся утилизации данного канала. В таких случаях обычно говорят: «Ну кто же знал» или «100% надежных систем не бывает» и тд.



Грамотная архитектура + правильный мониторинг = отказоустойчивость



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




  • приведение архитектуры сети хранения данных в соответствие с «SAN best practices»

  • развертывание системы мониторинга



Если про SAN best practices есть много литературы и курсов обучения, и можно пригласить крутых специалистов из интегратора для проведения экспертизы, то выбрать верный способ создать хорошую систему мониторинга SAN сети не так легко. Это можно объяснить жесткой привязкой: разработчик ПО — изготовитель коммутаторов. Я конечно не хочу сказать, что Cisco Fabric Manager или Brocade Network Advisor плохи, но они не позволяют делать все то, что необходимо на мой взгляд для повышения отказоустойчивости SAN сети.



Что делать



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

Разберем реализацию мониторинга CRC ошибок на портах SAN свичей brocade, большинство остальных параметров можно мониторить аналогичным образом.



Шаг первый, протокол сбора данных


Информацию о числе CRC ошибок можно получать с коммутаторов разными способами (snmp, https, telnet и ssh) мой выбор пал на последний т.к. telnet не безопасен и его лучше отключать, https сложен для извлечения конкретных значений, а snmp дерево может значительно меняться как на разных свичах, так и при переходе на новый FOS.



Шаг второй, метод сбора данных


Для работы с ssh лучше всего адаптирован linux в связке bash+expect, этим методом можно подключаться по ssh с диалоговым вводом команд.



Шаг третий, где хранить


Тут большой разницы нет, можно хранить хоть в текстовых файлах, но мы рассмотрим пример с mysql. Весь мониторинг реализован в двух скриптах:



porterrshow.sh — сбор информации и поиск инкремента значений CRC ошибок

expect.tcl — подключение по ssh



и трех txt файлах:

temp.txt — буфер данных

switches.txt — список san свичей в формате имя логин пароль на каждой строке

crc.txt — отчет о найденных CRC ошибках



Select запрос ищет инкремент роста CRC ошибок по сравнению с данными полученными один час назад, соответственно запуск скрипта необходимо производить один раз в час, причем начать и закончить свою работу скрипт должен в одном и том же часу. Данное ограничение можно легко обойти, если ввести поле порядкового номера запуска скрипта, либо потерять в производительности и задать более сложное условие выборки значений времени. На сервере должны быть установлены пакеты expect, mysql и ssh клиент. В базе данных dbname должен присутствовать пользователь user с правами на чтение и запись в таблицу tablename. В таблице tablename получаем данные аналогичные выводу команды porterrshow на свиче + дата и время.



porterrshow.sh



#!/bin/bash

rm /var/scripts/temp.txt #Удаляем ранее созданный temp.txt
while read line #Читаем строку из файла switches.txt
do read sw user pass <<< $line #Разбиваем строку на переменные

n=0 #Обнуляем счетчик
while read line; #Читаем строку из вывода expect.tcl
do array[n]="$line"; n=$[n+1]; #Заполняем массив строками из вывода expect.tcl
done < <(/var/scripts/expect.tcl $sw $user $pass porterrshow) #Отправляем данные в цикл

if echo ${array[4]} | grep -q '='; #Проверяем с какой строки начинается вывод полезной информации
then k=5;
else k=4;
fi;

for i in `seq $k $[n-1]`; #В последней строке данных нет
do read a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 <<< ${array[i]}; #Разбиваем строку на значения
(echo $sw,${a1%:},`date +%F`,`date +%T`,$a2,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$a10,$a11,$a12,$a13,$a14,$a15,$a16,$a17) >> temp.txt #Формируем подгрузочный файл
done;

done < /var/scripts/switches.txt #Читаем файл со списком свичей

mysql -uuser -ppass dbname << EOF;
LOAD DATA LOCAL INFILE "temp.txt" INTO TABLE tablename FIELDS TERMINATED BY ',';
EOF
#Загружаем данные в БД

(mysql -uuser -ppass dbname << EOF
select new.switch, new.port, new.crcerr-old.crcerr from tablename new, tablename old where new.switch=old.switch and new.port=old.port and new.date=old.date and new.crcerr!=old.crcerr and new.crcerr!=0 and new.date=curdate() and hour(new.time)=hour(now()) and hour(old.time)=hour(now())-1;
EOF
) > /var/scripts/crc.txt #Проверяем инкремент CRC по портам и пишем отчет в файл

if grep -q 'switch' /var/scripts/crc.txt
then
cat /var/scripts/crc.txt | mailx -r SAN_Switch_CRC_Tester -s "CRC errors is increased" sanadmin1@mywork.com
fi
#Отправляем информацию администратору


expect.tcl



#!/usr/bin/expect

#Устанавливаем таймаут соединения 10 сек
set timeout 10

#Проверям число параметров передаваемых скрипту
if {$argc != 4} {
puts "Usage $argv0 host user pass command"
exit 1}

#Назначаем параметры переменным
set host [lindex $argv 0]
set user [lindex $argv 1]
set pass [lindex $argv 2]
set command [lindex $argv 3]

#Производим подключение по SSH
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no $user@$host $command
expect *assword:
send "$pass\r"
expect eof


Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/281432/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
Chizz_TecTeP

ЦИТАТА #438830

Вторник, 12 Апреля 2016 г. 13:07 (ссылка)

Это цитата сообщения rss_bash_org_ru Оригинальное сообщение

Цитата #438830



Слушая все эти истории про коллекторов меня не перестаёт мучить один вопрос. А если я плачу кредит вовремя, могу я прийти в банк и у них на стене написать что-то вроде "Иванов из 7 квартиры вовремя платит!"?

http://bash.im/quote/438830

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[Из песочницы] Zenity на службе у системного администратора

Среда, 06 Апреля 2016 г. 11:42 (ссылка)

Задумала как-то одна компания перейти на ПО свободное. И скачали себе линукс на все компьютеры, и сервер с дисками заморскими поставили, и учетные записи для пользователей сделали. И приказал начальник чтобы все сотрудники поставили себе пароли заковыристые. А они хоть и послушали рассказы о том, что за зверь перед ними, а вот где поменять пароль не знают. Или в настройках найти не могут. А от консоли бегут сломя голову. И начинают бегать к админу со словами «админ-админушка, помоги найти кнопочку», и начинает админушка бегать да нервничать, от дум важных отвлекается...


Не секрет, что для многих пользователей (особенно не связанных напрямую с IT) переход на новую операционную систему и ПО часто проходит болезненно. И во многом это связано с привычками. Люди запоминают что где находится на их компьютере и, если все переставить — они теряются. В результате многие простые действия могут вызывать сложности, такие как потеря времени и нервов.



Появилась идея: а что, если для задачи, требующей незамедлительного вмешательства пользователя (вроде замены пароля из былины выше), еще не знакомого с интерфейсом системы, ему явно дать окно с возможностью эту задачу решить? В поисках простого решения я наткнулся на zenity. Это небольшая утилита, позволяющая выводить на экран диалоговые окна. Она использует GTK+ и, как оказалось, в большинстве популярных дистрибутивов линукса идет в комплекте. В дополнение к этому ее можно использовать прямо в скриптах на BASH, что дает возможность быстро «на коленке» сделать скрипт и запустить его у пользователя в определенное время. Рассмотрим пример:



function change_password() {
local passwords=$(zenity --forms --title="Change your password" \
--text="Set new password (minimum length 8 characters)" \
--separator="," \
--add-password="Your password" \
--add-password="Repeate password")

local password1=$( echo $passwords | awk -F ',' '{print $1}' )
local password2=$( echo $passwords | awk -F ',' '{print $2}' )

if [[ $password1 == $password2 ]]; then
if [[ ${#password1} == 0 ]]; then
zenity --warning --text "Please, select Your password"
change_password
return
fi

if [[ ${#password1} < 8 ]]; then
zenity --warning --text "Your password too easy."
change_password
return
fi

local username=$(whoami)

# закомментируем само изменение пароля
# чтобы незадачливый пользователь Ctrl+C - Ctrl+V случайно его себе не поменял
#echo "$username:$password1" | chpasswd

local expire_time=$(chage -l $username | awk 'FNR==2{print $4}')
local full_name=$(cat /etc/passwd | grep "^$username" \
| awk -F ':' '{print $5}' | awk -F ',' '{print $1}')

zenity --info --text "$full_name, Your password has been changed. Your new password expires: $expire_time"
else
zenity --warning --text "Passwords does not match"
change_password
return
fi
}

change_password


В результате мы получаем окошко с формой для пароля, которое «само покажется» вероятно с использованием утилиты at или ее аналога пользователю и ему останется только ввести свой новый пароль, сэкономив время и ему и администратору. Выглядит это примерно так (используется стандартное оформление окон из вашей системы):



image



Zenity не только показывает окно, но и выводит в стандартные вывод то, что пользователь в окне сделал. В нашем случае он заполнил два поля в форме. Нам нужно этот самый вывод перехватить. Таким образом мы можем получить значения всех полей из диалогового окна в одной строке через разделитель — по умолчанию символ "|", в примере мы заменяем его на запятую. Назначение параметров zenity говорят сами за себя, особенно если сразу смотреть на результат.



passwords=$(zenity --forms --title="Change your password" \
--text="Set new password (minimum length 8 characters)" \
--separator="," \
--add-password="Your password" \
--add-password="Repeate password")


Дальше нам остается только обработать полученные данные (проверка на длину меньше 8 символов для пароля — это для примера, никогда так не делайте!), и сообщить пользователю о результатах. Для этого как нельзя кстати оказались окна с сообщениями, которые создаются еще проще, чем с формами:



zenity --warning --text "Your password too easy." --width=300


image



В заключение мы можем успокоить пользователя с помошью еще одного сообщения, уже обратившись к нему по имени:



username=$(whoami)
expire_time=$(chage -l $username | awk 'FNR==2{print $4}')
full_name=$(cat /etc/passwd | grep "^$username" \
| awk -F ':' '{print $5}' | awk -F ',' '{print $1}')

zenity --info --width=400 --text "$full_name, Your password has been changed. Your new password expires: $expire_time"


image



Как вариант можно использовать и стандартные уведомления:



zenity --notification --window-icon="info" \
--text="$full_name, Your password has been changed. Your new password expires: $expire_time"


image



WARNING! В старых версиях пакета zenity есть баг, из-за которого процесс, создающий окно с уведомлением не может завершиться. Это решается добавлением ненулевого таймаута:



zenity --notification --window-icon="info" --text="..." --timeout=1


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



mark=$(zenity --scale \
--text "Rate your experience" \
--value=3 \
--min-value=1\
--max-value=5 \
--step=1)

if [[ $? == 0 ]]; then
zenity --notification --window-icon="info" --text="Thank You!" --timeout=1
fi


Названия опций интуитивно понятны и не требуют пояснений.



image



К сожалению, zenity не умеет заменять такую шкалу на звездочки (есть мнение, что звездочки интуитивно понятнее), но, вскоре нашелся аналог со списком:



zenity --list --text="What do you think about your PC?" \
--radiolist --column "Pick" --column "Opinion" \
TRUE "All is good" \
FALSE "All is good, but..." \
FALSE "I don't know" \
FALSE "Too dificult to use it" \
FALSE "A-A-A \(O_O)/ A-A-A" \
--height=350


image



С использованием cron`a можно раз в день запускать и смотреть результаты. Осталось только решить вопрос с передачей собранных данных на сервер. Кажется, хорошей идеей будет приобщить систему мониторинга, которая и так уже имеет агента на каждом компьютере в рамках эксперимента — и рисовать графики для опросов пользователей.



Несмотря на то, что примеры в этой статье явно не самые актуальные, я надеюсь, что они наведут кого-нибудь на интересные мысли по поводу использования графических интерфейсов в небольших скриптах для связи с пользователями. Возможно это будут важные сообщения для всех работников (в духе команды wall, только с окошком), оповещения о начале обеденного перерыва или голосования о месте проведения корпоратива. Хочу также отметить, что если вы знаете готовые программные решения для такого рода задач — вы можете поделиться ими в комментариях, а мои скрипты «на коленке» — это не более чем интересный эксперимент, который может в последствии перерасти в нечто большее.



В заключение еще раз привожу ссылку на мануал по zenity: https://help.gnome.org/users/zenity/stable/

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/281034/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Улучшаем работу в консоли

Пятница, 01 Апреля 2016 г. 14:13 (ссылка)

Наверняка многие делали так, как на картинке, но вот только у них при этом выдалась ошибка типа «файл не найден». Давайте исправим эту проблему, чтобы при таких очевидных опечатках происходило именно то, что вы хотели. То есть, когда вы пишете «ssh », происходил заход в директорию и наоборот, когда вы делаете «cd » происходит заход по ssh. Ну и заодно сделаем то же самое для vim, чтобы 2 раза не вставать.





Скрипты с #!/bin/sh в начале под названием ssh/cd/vim



Если мы попробуем пойти наивным путем и просто написать скрипты под названием «ssh», «cd» и «vim», то реально запускать ни vim, ни ssh у нас не получится из-за бесконечной рекурсии:



#!/bin/sh
# нужно назвать файл ssh, cd или vim и поместить скрипт в $PATH перед настоящими утилитами,
# например в директорию /bin, которая почти всегда идет перед /usr/bin, в которой как правило лежат vim и ssh

# проверим сначала, не является ли первый аргумент ($1) директорией ([ -d ... ] означает проверку на директорию, см. man test для деталей)
if [ -d "$1" ]; then
cd "$1"
# иначе, если это файл (-f), то запустим vim
elif [ -f "$1" ]; then
vim "$1"
# поскольку определить, что это hostname сложнее всего, будем считать, что первый аргумент это hostname, если это не файл и не директория
else
ssh "$1"
fi




Такой подход будет работать для команд vim и ssh, если назвать скрипт как-то по-другому, чтобы мы не обращались сами к себе, или если прописать полные пути до vim и ssh (тогда это будет непортируемо, поскольку в разных системах эти утилиты могут жить в разных директориях).



Однако, для команды cd такое работать не будет от слова «совсем», к сожалению, поскольку cd является встроенной командой в bash. То есть, не будет работать ни «cd localhost», ни «ssh ».



Также, мы всегда смотрим только на первый аргумент ($1), и передача дополнительных флагов не будет работать. Например, нельзя будет выполнить команду «ssh localhost uptime» и вместо этого мы просто зайдем по ssh на localhost.



Улучшенный скрипт



Давайте попробуем решить хотя бы проблему с тем, что мы не передаем аргументы команде. Для этого существует очень забавная конструкция "$@", которая служит для передачи списка аргументов в команды «как есть», с учетом экранирования. Это отличается от "$*", которая склеит все аргументы в один, и также отличается от $* (без кавычек), которая превратит аргументы с пробельными символами в разные аргументы.



Итак, улучшенный вариант скрипта:

#!/bin/sh
if [ -d "$1" ]; then
echo 'Пожалуйста, смените сами директорию на следующее: cd ' "$@"
elif [ -f "$1" ]; then
vim "$@"
else
ssh "$@"
fi




Теперь команда «vim localhost uptime» будет работать, если вы поместили этот скрипт в /bin/vim. Но все остальные проблемы останутся, к сожалению. Проблему с cd внутри скрипта мы решили с помощью вызова echo, но всё же хотелось получить решение получше, чтобы директория при этом менялась и нам не приходилось самим набирать команду cd.



Алиасы в bash



Лично я знаю 2 способа подменить встроенные команды в bash: алиасы и функции. Однако, возможности алиасов сильно ограничены и им недоступны аргументы, которые передаются в функцию:



$ alias cd='echo ALL YOUR BASH ARE BELONG TO US; cd'
$ cd
ALL YOUR BASH ARE BELONG TO US
$




Алиасы в баше работают весьма просто и внутри других алиасов не разворачиваются. В данном случае вышеприведенный пример — это почти всё, что можно сделать с помощью алиасов в баше.



Функция sshcdvim



Поскольку у нас почти не остается выбора, давайте напишем функцию. Она будет выглядеть следующим образом:



function sshcdvim() {
if [ -d "$1" ]; then
cd "$@"
elif [ -f "$1" ]; then
vim "$@"
else
ssh "$@"
fi
}




Этот код нужно поместить в ".bashrc" и перезапустить bash. Теперь вы можете пользоваться функцией sshcdvim, которая сама выберет, что запускать.



Однако, если вы захотите назвать свою функцию cd, vim или ssh, то опять получите бесконечную рекурсию при попытке использования.



Понятия builtin и command в bash



Чтобы объявленные функции в bash не влияли на исполнение скриптов, существуют 2 ключевых слова в bash: builtin и command.

Ключевое слово builtin перед именем команды указывает интерпретатору, что не нужно запускать функцию или команду, а нужно запустить встроенную команду. В нашем случае такой встроенной командой является cd.

Ключевое слово command делает то же самое, что и builtin, но используется для настоящих команд. В нашем случае настоящими командами являются vim и ssh, поэтому их и нужно использовать.



Конечный вариант будет выглядеть так:

function ssh() {
if [ -d "$1" ]; then
builtin cd "$@"
elif [ -f "$1" ]; then
command vim "$@"
else
command ssh "$@"
fi
}




Для команд vim и cd можно поменять проверки местами, если необходимо.



Воспользовавшись такой магией баша, вы сможете удивлять коллег по работе и даже показывать фокусы по телевизору! Надеюсь, вам понравилась статья и она окажется полезной для вашей повседневной работы.



Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/280690/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Объединение видеофрагментов с нескольких камер и синхронизация их по времени

Понедельник, 15 Февраля 2016 г. 08:33 (ссылка)


В системе дистанционного надзора (СДН), обзор которой был сделан в предыдущей статье, для управления медиапотоками используется медиасервер Kurento, позволяющий записывать потоки, где каждый поток — это отдельный файл. Проблема заключается в том, что при просмотре протокола экзамена нужно воспроизводить три потока одновременно с синхронизацией потоков по времени (веб-камера испытуемого со звуком, веб-камера проктора со звуком и рабочий стол испытуемого), причем на протяжении всего экзамена каждый поток может быть разбит на несколько фрагментов. Эта статья о том, как удалось решить данную проблему, а также организовать сохранение видеозаписей на WebDAV сервер всего одним bash-сценарием.



Воспроизведение видеоархива СДН

Читать дальше →

https://habrahabr.ru/post/277179/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[Из песочницы] Zimbra: удаление случайных или ненужных писем

Пятница, 12 Февраля 2016 г. 12:52 (ссылка)


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



Но если случается, что один сотрудник вместо того, чтобы отправить очень приватно-пикантное сообщение другому, отправляет его (сообщение) всему холдингу… Ждать день, когда стартанет автоматическая очистка — не вариант, а удалить надо сейчас и у всех.



Под катом описание того, как это реализовано у меня.

Читать дальше →

https://habrahabr.ru/post/277117/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Сторожевой таймер для 4G модема в CentOS 7

Среда, 20 Января 2016 г. 12:23 (ссылка)


Эта статья является дополнением моей предыдущий публикации о настройке домашнего роутера / файл-сервера. Здесь речь пойдет об проблеме автоматического переподключения к интернету при зависании 4G USB модема. На оригинальность идеи не претендую, просто хочу поделиться с читателями своим решением данной проблемы.



Читать дальше →

http://habrahabr.ru/post/275551/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество

Следующие 30  »

<bash - Самое интересное в блогах

Страницы: [1] 2 3 ..
.. 10

LiveInternet.Ru Ссылки: на главную|почта|знакомства|одноклассники|фото|открытки|тесты|чат
О проекте: помощь|контакты|разместить рекламу|версия для pda