Posts Tagged ‘пинизи’

Linux + scheduled tasks

Monday, March 25th, 2013

Може да ви се наложи да стартирате команда по часовник или по време когато не сте на машината.
Единият вариант който се използва е cron, но това е по-скоро за задачи, които се повтарят във времето. Няма да го разлеждаме, тъй като нета е пълен с примери и на всеки рано или късно му се е налагало да си блъска главата с него 🙂

По-интересното е да направим единично стартиране на задача по зададено време.

В Линукс това става много лесно с командата `at`:


(19:18:49)[ivanatora@~]$ at 19:20
warning: commands will be executed using /bin/sh
at> beep
at>
job 17 at Mon Mar 25 19:20:00 2013

Забележка: това <EOT> предполагам че е end-of-terminal и се получава с CTRL+D.
В случая задачата която ще се стартира е `beep`. Можете да напишете цял скрипт в промпта на `at` или да укажете външен файл който съдържа скриптираните задачи чрез `at [-f file]`. Отбележете че интерпретаторът, с който се изпълнява скрипта в случая е /bin/sh – това ще ви се отрази ако искате да скриптирате по-сложни задачи използвайки вградените възможности. Естествено, нищо не ви пречи да стартирате скрипт писан на какъвто и да е език:


(19:23:46)[ivanatora@~]$ at 19:50
warning: commands will be executed using /bin/sh
at> php /home/ivanatora/test.php
at>
job 18 at Mon Mar 25 19:50:00 2013

Списък с текущите активни задачи може да видите с `atq`:


(19:24:02)[ivanatora@~]$ atq
18 Mon Mar 25 19:50:00 2013 a ivanatora

Може да се зачудите къде отиде задача 17? Ами тя изтече докато напиша тези редове 😉

Може да изтривате задачи от списъка с `atrm`:


(19:25:35)[ivanatora@~]$ atrm 18
(19:26:13)[ivanatora@~]$ atq
(19:26:37)[ivanatora@~]$

Може да преглеждате с детайли определена задача с `at [-c job]`:

(19:27:20)[ivanatora@~]$ at 19:30
warning: commands will be executed using /bin/sh
at> beep
at>
job 19 at Mon Mar 25 19:30:00 2013
(19:27:37)[ivanatora@~]$ at -c 19
#!/bin/sh
# atrun uid=1000 gid=1000
# mail ivanatora 0
umask 2
SSH_AGENT_PID=2367; export SSH_AGENT_PID
GPG_AGENT_INFO=/tmp/gpg-xsDFU4/S.gpg-agent:2368:1; export GPG_AGENT_INFO
XDG_SESSION_COOKIE=4784344ffacd7f8cf96108324bae42fb-1364229708.104884-44687589; export XDG_SESSION_COOKIE
WINDOWID=37748745; export WINDOWID
GNOME_KEYRING_CONTROL=/tmp/keyring-bylSRi; export GNOME_KEYRING_CONTROL
GTK_MODULES=canberra-gtk-module; export GTK_MODULES
USER=ivanatora; export USER
LS_COLORS=rs=0:di=01\;34:ln=01\;36:mh=00:pi=40\;33:so=01\;35:do=01\;35:bd=40\;33\;01:cd=40\;33\;01:or=40\;31\;01:su=37\;41:sg=30\;43:ca=30\;41:tw=30\;42:ow=34\;42:st=37\;44:ex=01\;32:\*.tar=01\;31:\*.tgz=01\;31:\*.arj=01\;31:\*.taz=01\;31:\*.lzh=01\;31:\*.lzma=01\;31:\*.tlz=01\;31:\*.txz=01\;31:\*.zip=01\;31:\*.z=01\;31:\*.Z=01\;31:\*.dz=01\;31:\*.gz=01\;31:\*.lz=01\;31:\*.xz=01\;31:\*.bz2=01\;31:\*.bz=01\;31:\*.tbz=01\;31:\*.tbz2=01\;31:\*.tz=01\;31:\*.deb=01\;31:\*.rpm=01\;31:\*.jar=01\;31:\*.war=01\;31:\*.ear=01\;31:\*.sar=01\;31:\*.rar=01\;31:\*.ace=01\;31:\*.zoo=01\;31:\*.cpio=01\;31:\*.7z=01\;31:\*.rz=01\;31:\*.jpg=01\;35:\*.jpeg=01\;35:\*.gif=01\;35:\*.bmp=01\;35:\*.pbm=01\;35:\*.pgm=01\;35:\*.ppm=01\;35:\*.tga=01\;35:\*.xbm=01\;35:\*.xpm=01\;35:\*.tif=01\;35:\*.tiff=01\;35:\*.png=01\;35:\*.svg=01\;35:\*.svgz=01\;35:\*.mng=01\;35:\*.pcx=01\;35:\*.mov=01\;35:\*.mpg=01\;35:\*.mpeg=01\;35:\*.m2v=01\;35:\*.mkv=01\;35:\*.webm=01\;35:\*.ogm=01\;35:\*.mp4=01\;35:\*.m4v=01\;35:\*.mp4v=01\;35:\*.vob=01\;35:\*.qt=01\;35:\*.nuv=01\;35:\*.wmv=01\;35:\*.asf=01\;35:\*.rm=01\;35:\*.rmvb=01\;35:\*.flc=01\;35:\*.avi=01\;35:\*.fli=01\;35:\*.flv=01\;35:\*.gl=01\;35:\*.dl=01\;35:\*.xcf=01\;35:\*.xwd=01\;35:\*.yuv=01\;35:\*.cgm=01\;35:\*.emf=01\;35:\*.axv=01\;35:\*.anx=01\;35:\*.ogv=01\;35:\*.ogx=01\;35:\*.aac=00\;36:\*.au=00\;36:\*.flac=00\;36:\*.mid=00\;36:\*.midi=00\;36:\*.mka=00\;36:\*.mp3=00\;36:\*.mpc=00\;36:\*.ogg=00\;36:\*.ra=00\;36:\*.wav=00\;36:\*.axa=00\;36:\*.oga=00\;36:\*.spx=00\;36:\*.xspf=00\;36:; export LS_COLORS
XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session0; export XDG_SESSION_PATH
XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0; export XDG_SEAT_PATH
SSH_AUTH_SOCK=/tmp/ssh-UytBrOmq2318/agent.2318; export SSH_AUTH_SOCK
DEFAULTS_PATH=/usr/share/gconf/fluxbox.default.path; export DEFAULTS_PATH
XDG_CONFIG_DIRS=/etc/xdg/xdg-fluxbox:/etc/xdg; export XDG_CONFIG_DIRS
DESKTOP_SESSION=fluxbox; export DESKTOP_SESSION
PATH=/home/ivanatora/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/ivanatora/bin/; export PATH
PWD=/home/ivanatora; export PWD
GNOME_KEYRING_PID=2307; export GNOME_KEYRING_PID
LANG=en_US.UTF-8; export LANG
MANDATORY_PATH=/usr/share/gconf/fluxbox.mandatory.path; export MANDATORY_PATH
UBUNTU_MENUPROXY=libappmenu.so; export UBUNTU_MENUPROXY
PS1=\\[\\033[1\;34m\\]\(\\t\)\\[\\033[0m\\][\\u@\\[\\033[1\;33m\\]\\w\\[\\033[0m\\]]\\\$\ ; export PS1
GDMSESSION=fluxbox; export GDMSESSION
SPEECHD_PORT=7560; export SPEECHD_PORT
COLORFGBG=15\;default; export COLORFGBG
HOME=/home/ivanatora; export HOME
SHLVL=2; export SHLVL
LOGNAME=ivanatora; export LOGNAME
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-rCyQHFVg4i,guid=31de69d47f7c412295741b5100000041; export DBUS_SESSION_BUS_ADDRESS
XDG_DATA_DIRS=/usr/share/fluxbox:/usr/local/share/:/usr/share/; export XDG_DATA_DIRS
LESSOPEN=\|\ /usr/bin/lesspipe\ %s; export LESSOPEN
BROWSER=firefox; export BROWSER
LESSCLOSE=/usr/bin/lesspipe\ %s\ %s; export LESSCLOSE
COLORTERM=rxvt-xpm; export COLORTERM
XAUTHORITY=/home/ivanatora/.Xauthority; export XAUTHORITY
cd /home/ivanatora || {
echo 'Execution directory inaccessible' >&2
exit 1
}
beep

 

Ау, уау, какво стана? Къде е задачата?

Задачата е най-отдолу, но за да стигне до нея `at` зарежда доста от променливите на обкръжението. Който е писал и дебъгвал крон задачи знае колко е досадно да разчиташ на определена променлива от средата, а тя да не е това което трябва…И въпреки всичкото това зареждане тук ни липсва една важна променлива, която ако сетнем ръчно ни отваря нови хоризонти. А именно – DISPLAY. По подразбиране дефаултния дисплей е “:0.0” и ако го използваме, може да стартираме задача, която работи с Х-а.

Една примерна грубa елементарна напомнянка:


(19:34:37)[ivanatora@~]$ at 19:36
warning: commands will be executed using /bin/sh
at> beep
at> DISPLAY=:0.0 xmessage "remember to eat dinner!"
at>
job 23 at Mon Mar 25 19:36:00 2013

Възможните формати за подаване на времето за стартиране е доста обширен и може да го видите в /usr/share/doc/at/timespec

Watermark Signature

Wednesday, April 18th, 2012

Поставяне на воден знак

Обикновено водния знак може да бъде два вида:
* текст, който се изписва върху снимката или
* картинка която се наслагва отгоре.

Всеки може да хване произволен шрифт от нета и да си напише името. Нека сме по-оригинални и да си направим воден знак, който никой друг не може да има – да се подпишем 🙂

Намерете хубав химикал – трябва да пише равномерно и да не пуска мастилото на капки. Изберете хартия – може да е чисто бял лист, може да има редове – зависи какъв ефект желаете да постигнете. Хартията не е необходимо да е перфектно искряща бяла. И жълтеникава да е – после ще се оправи. Подпишете се няколко пъти. Когато имате няколко добри резултата можете да извадите фотоапарата.

Сложете го на ръчен фокус като го забиете на възможно най-близкото разстояние. Обектива – в най-дългия край. Целта е да получите голямо и ясно изображение на подписа. Пуснете си live view с най-голямото увеличение за да следите как е фокуса и премествайте леко назад-напред апарата докато фокуса стане перфектен. Снимайте със светкавица като използвате най-голямата възможна разделителна способност.

Следва лека обработка. Аз съм ползвал GIMP, но нещата не са по-различни в Photoshop или всеки друг свестен редактор.
* кропваме избрания подпис
* вдигаме контраста и намаляме яркостта – целта е да смачкаме цветовете и да получим открояващо се монохромно изображение (не прекаляваме с яркостта, защото по някое време ще почнем да виждаме писаното отзад на листа 🙂 )


* ако е нужно премахваме всички цветове (desaturate)
* по желание минаваме редовете с една бяла четка
* по желание удебеляваме подписа – избираме всичко по черен цвят, увеличаваме селекцията с 1-2-3 пиксела и наливаме с черната кофа
* минаваме с бялата четка и оправяме ако са се появили разни дефекти
* ако искаме да накривим нещо (или да оправим кривина) ползваме Filters -> Distorts -> Curve Bend

На този етап би трябвало да имате черно-бяло изображение, в което единия цвят е фона, а другия – подписа. Сега да помислим как ще изглежда водния знак върху произволна снимка (а ще очакваме за в бъдеще да има много снимки подпечатани с него). Ако изкараме подписа с бял цвят, ще изглежда добре върху тъмен фон, но не и върху светъл. Ако го изкараме с черен цвят – обратно. Едно възможно решение е да му сложим полупрозрачен фон, който да го откроява:
* добавяме Alpha слой към изображението (ако вече няма такъв)
* Layers -> Transparency -> Color to Alpha – и правим фоновия цвят (белия) да е прозрачен
* правим един нов слой и го позиционираме под основата
* правим една правоъгълна селекция със заоблени краища върху подписа и я наливаме с цвят обратен на цвета на текста
* слагаме прозрачност на втория слой на 50% или по усмотрение
* изравняваме изображението и го запазваме в PNG формат (заради прозрачностите)

Вече имаме водния знак, който ще ни стане запазена марка. За да го ползваме върху снимка, обаче може би ще трябва да го посмалим малко – при мен изображението беше с размери 1700х400. Запазете оригиналния файл все пак.

От тук натам можем да отворим снимката, която ще маркираме, да добавим изображението с водния знак отгоре и да запазим новия вариант (пазете си оригиналите на снимките отделно). Но за да е по-интересно, нека автоматизираме този процес.

ImageMagick е комплект с елементарни инструменти за графична обработка. Могат да конвертират формати, да правят колажи, да кропват, да комбинират снимки, да слагат маски… poor man’s photoshop 🙂 Естествено безплатен е и се ползва през командния ред, което го прави много удобен за скриптове.

Създаваме файла /bin/wmpic.sh със следното съдържание:

#!/bin/bash
filename=`basename "$1" | sed 's/\.\([^\/\.]*$\)//'`
composite -gravity southeast -quality 90 ~/watermark_small.png $1 ${filename}_WM.jpg
echo "Done: ${filename}_WM.jpg"

Няма да обяснявам кое какво прави – имате man страници на bash и на composite 🙂

Резултата е че с един ред правим изображение с воден знак:

$ wmpic.sh IMG_1789_90_91_fused.jpg
Done: IMG_1789_90_91_fused_WM.jpg

Готин Bash хак за изтриване на път

Tuesday, November 24th, 2009

Забелязъл съм нещо интересно, което може да се прави в csh, но работи по друг начин в bash.
Да речем че съм написал някакъв дълъг път:

/mnt/storage/mp3/Manowar

… и се сетя че всъщност не съм имал предвид “Manowar” като последна директория, а “rammstein”. Единия начин да оправя това е като набия 7 backspace-а и да изтрия всяка буква поотделно, докато стигна до наклонената черта. Ами ако се сетя че “rammstein” не е в “mp3”, а в “/mnt/storage/Music”? Тогава чаткането по backspace става още повече.
В csh това става елементарно с CTRL-W – комбинацията изтрива всичко от командния ред до предната наклонена черта.
Така

/mnt/storage/mp3/Manowar

става

/mnt/storage/mp3/

с един CTRL-W. Следващия CTRL-W ще махне “mp3/”, следващия ще махне “storage/” и т.н.
Гугъл върна един резултат на това търсене – тук в Shallow Thoughts.
На кракто решението е следното:
Това отива в ~/.inputrc:

set bind-tty-special-chars Off

А това отива в ~/.bash_profile:

bind '\C-w:backward-kill-word'

Шела се рестартира (logout -> login) и трябва да работи.
Обяснение на дълго защо се случва това – в горния линк.

Закоментиране на цял блок код с един знак

Sunday, November 1st, 2009

Този бърз хак работи само в езици, които поддържат коментари от вида “//” за коментиране на ред и такива от вида “/* … */” за коментиране на блок.
Да вземем този блок:

  1.  
  2. blqk();
  3. puf();
  4. paf();
  5.  

Да го закоментираме целия:

  1.  
  2. /*
  3. blqk();
  4. puf();
  5. paf();
  6. */
  7.  

И да закоментираме затварящия коментар 🙂

  1.  
  2. /*
  3. blqk();
  4. puf();
  5. paf();
  6. //*/
  7.  

В този момент целия блок е закоментиран. Ако сега добавим единична “/” пред отварящия коментар, коментарите ще отпаднат и блокът ще се разкоментира:

  1.  
  2. //*
  3. blqk();
  4. puf();
  5. paf();
  6. //*/
  7.  

Изпробвано е и работи в С и РНР. Ако имате пуснато оцветяване на кода в редактора, който ползвате (и оцветяването работи добре в реално време), ще видите интерсна гледка при добавяне и премахване на магическата “/” 🙂

Интегриране на GCC във Vim

Wednesday, March 25th, 2009

Вдъхновен от поста на един приятел, реших че може малко да си улесня живота като добавя бързи бутони за Compile и CompileRun във vim 🙂 Пиниза наистина е лесен и си струва. Следните редове се добавят във .vimrc:

  1.  
  2. map <F9> :call CompileRun()<CR>
  3. map <F5> :call Compile()<CR>
  4. func! CompileRun()
  5.         exec "w"        
  6.         exec "!gcc % -o %< && ./%<"
  7. endfunc
  8. func! Compile()
  9.         exec "w"
  10.         exec "!gcc % -o %<"
  11. endfunc
  12.  

След това докато редактирате .с файл цъкате F5 и файла се компилира, F9 и се компилира и изпълнява. Евентуално може да бъде добавена и функцийка за make с Makefile.