0
<< предыдущая заметкаследующая заметка >>
15 августа 2013
Screenshot в Linux

Друзья, подскажите.

Мне нужна под Linux программка-скриншот, которая бы при запуске по горячим клавишам (вероятно, с определенными параметрами в командной строке) делала скриншот активного окна в файл с уникальным именем в определенную папку и так же тихо удалялась, не возмущая спокойствие дисплея своими дурацкими окнами, менюшками и вариантами событий.

Из того, что я пробовал, такое умеет только shutter -a -e -o file.png Но он написан весь из себя на питоне, поэтому полчаса запускается и полчаса успокаивается. А мне нужно, чтобы один миг, а не четыре с половиной секунды.

screengrab — умеет создавать файл уже при запуске. Но после этого он гордо разворачивает свое окно в центре дисплея с таким ощущением собственной нужности, будто он как минимум Winword и ожидает, что пользователь в нем сейчас начнет многочасовую работу.

screenshot — не имеет опций служебной строки, снимок делает в папку ~/Документы/Изображения/ и открывает на экране совершенно мне не нужный файл-менеджер.

ksnapshot, gnome-screenshot, xfce4-screenshooter — делают снимок окна и открывают Диалог, как быть дальше. На хуй мне с ними вести диалог?

mini-screenshoter (The LXDE Screenshot Tool) и kde4-ksnapshot — непонятно, где их искать после установки. Блять, обожаю пакеты, которые не запускаются по своему заявленному имени.

xwd (xwd -nobdrs -silent | xwdtopnm | pnmtopng > Screenshot.png) — не умеет делать скриншот самостоятельно, ждет клика мышкой.

scrot -u — не работает, потому что опция "-u" есть не в любом Линуксе. У меня нет.

UPD:

Спасибо за советы sin и T.Igor. Оказалось, более быстрым решением, чем shutter, является самотык из кучи линуксовых команд:

xwd -id `xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | awk {'print $2'}` -nobdrs -silent | xwdtopnm | pnmtopng > file.png

Конструкция состоит по большому счету из двух частей — одна выясняет активное окно, другая делает скриншот. Были варианты и той и другой части, я поизмерял производительность: вариант с grep оказался медленнее, чем уточненные опции xprop, а компашка "xwd | xwdtopnm | pnmtopng" оказалась в несколько раз производительнее утилитки import из ImageMagic (чья тормознутость давно ни для кого не тайна).

измерялка производительности
#!/bin/sh

date

i=0 ; while [ "$i" -lt 100 ] ; do i=$(($i+1)) ; echo "test #$i"

#id=`xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | awk {'print $2'}`
#id=`xprop -root|grep "^_NET_ACTIVE_WINDOW(WINDOW)" | awk {'print $5'}`

#xwd -id $id -nobdrs -silent | xwdtopnm | pnmtopng > file.png
#import -window $id file.png

done

date

В итоге я сделал себе такой скриптик screenshot.sh и повесил его на горячие клавиши:


#!/bin/sh
name="/home/8gb/screen/"`date +%Y%m%d-%H%M%S-%N`
xwd -id `xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | awk {'print $2'}` -nobdrs -silent | xwdtopnm | pnmtopng > $name.png
konsole -e echo &

Обратите внимание: "konsole -e echo &" нужно, чтобы экран мигнул и было заметно, что скриншот сработал.

<< предыдущая заметка следующая заметка >>
пожаловаться на эту публикацию администрации портала
архив понравившихся мне ссылок
Оставить комментарий
Linux Firefox
 Санкт-Петербург
0
0
SunChaser
Этот человек не загрузил свой юзерпик, и я подобрал ему этот. Человек, пишущий такое, должен именно так выглядеть, верно?
kde4-ksnapshot это и есть просто ksnapshot
Linux Firefox
 Санкт-Петербург
0
0
SunChaser
Этот человек не загрузил свой юзерпик, и я подобрал ему этот. Человек, пишущий такое, должен именно так выглядеть, верно?
есть еще scrot, но он не умеет брать активное окно и будет ждать клика по окну

xfce4-screenshooter до версии 1.6 имел опцию --hide, но ее выпилили (

а shutter (он на перле, а не на змее) долго запускается только 1 раз. я бы таки им воспользовался
Linux Firefox
0
0
читающий
Этот человек не загрузил свой юзерпик, и я подобрал ему этот. Человек, пишущий такое, должен именно так выглядеть, верно?
Неправда ваша, scrot всё это умеет. Читайте man.
Linux Firefox
 Москва
0
0
Леонит Каганофф
расскажите
Linux Firefox
0
0
SunChaser
Этот человек не загрузил свой юзерпик, и я подобрал ему этот. Человек, пишущий такое, должен именно так выглядеть, верно?
scrot version 0.8, Fedora 19 — нет такой опции
Linux Firefox
 Москва
0
0
Леонит Каганофф
[lleo@lleo]$ scrot -u
scrot: invalid option -- 'u'
Linux Firefox
0
0
SunChaser
судя по всему эти люди — убунтоводы и у них особый уличный scrot. у меня на федоре тоже нет опции -u
Linux Firefox
0
0
sin
Этот человек не загрузил свой юзерпик, и я подобрал ему этот. Человек, пишущий такое, должен именно так выглядеть, верно?
Возможно, подойдет import из состава ImageMagick (есть почти в любом дистрибутиве)

Вот так: import -window root /путь/к/скриншоту.png
Linux Opera
3
0
sin
Этот человек не загрузил свой юзерпик, и я подобрал ему этот. Человек, пишущий такое, должен именно так выглядеть, верно?
Ойй, затупил, это весь рабочий стол будет. Активное окно вот так:

import -window `xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | awk {'print $2'}` xxx.png
Linux Firefox
 Москва
0
0
Леонит Каганофф
о! спасибо!
Windows Opera
2
0
Konstantin Vlasov
Для программ, которые непонятно где искать, можно воспользоваться командой rpm -ql имя_пакета или dpkg -L имя_пакета, будет выведен полный список принадлежащих пакету файлов. Если дофига их, то можно грепнуть по 'bin'.
По сабжу, к сожалению, не подскажу. Про одну подобную утилитку слышал, но она тоже питоновская.
Mac Safari
0
0
braintunic
А если это пакет из серии "Запустите configure; Запустите make; Запустите make install"? :)
Windows Opera
0
0
Konstantin Vlasov
Обычно всё-таки пакетами называют не сорсовые тарболлы, а файлы, подготовленные для работы с пакетным менеджером.
Windows Firefox
0
0
braintunic
Лео, в измерялке производительности, для запуска цикла, вот эту громоздкую конструкцию:
i=0 ; while [ "$i" -lt 100 ] ; do i=$(($i+1)) ; echo "test #$i" ; done
(наверняка же часто приходится использовать?)
можно заменить вот таким компактным выражением:
for ((i=0;i<=100;i++)) do echo "test #$i"; done
Linux Opera
 Москва
0
0
Леонит Каганофф
Шо, прямо на /bin/sh такое?
Windows Firefox
0
0
braintunic
Зависит от системы, конечно :)
На Red Hat и Fedora - да, сработает прямо на /bin/sh (который у них просто симлинк на /bin/bash)

Но у вас же наверное Ubuntu? А в Ubuntu /bin/sh вроде бы слинкован с dash?
Да, тогда наверное не сработает с /bin/sh
Но почему бы не писать скрипты на /bin/bash? - много приятных улучшений ;)
Linux Firefox
 Москва
0
0
Леонит Каганофф
Честно сказать, я обычно использую для всего подряд исключительно консольный php. Это вчерась было исключение ;)
Mac Safari
1
0
braintunic
Так уж для всего подряд php?))
Неделю назад был пост про настройку LXDE - и там ты давал свой bash-скрипт для переключения дисплея.
А еще не так давно ты давал свои недурные bash-скрипты для массовой обработки файлов фотографий.
Я потому и подумал, что для тебя bash является каждодневным инструментом, иначе бы я и не пытался влезать в эти тонкости ;)

Ну и в общем случае, bash таки куда больше подходит для простых системных рутинных задач, не связанных с web-программированием или с обработкой XML.
Хотя это уже конечно на любителя! ;)
(надеюсь здесь не начнется холивар между сторонниками bash, php, python, perl, etc.)
Linux Firefox
1
0
читающий
Этот человек не загрузил свой юзерпик, и я подобрал ему этот. Человек, пишущий такое, должен именно так выглядеть, верно?
Вот тебе скрипт, вешай на любую горячую клавишу:

#!/bin/bash
set -e
cd /моя/папка/со/скриншотами
scrot -u
play /звуки/скришнот_сделан_успешно.wav
Linux Firefox
 Москва
0
0
Леонит Каганофф
хм...
а что такое set -e ?!
Linux Firefox
0
0
andrewsh
«Если что-то сломается — карррамба!»
Mac Safari
1
0
braintunic
Abort on error.
По set -e, при первом же падении по ошибке любой команды (exit status != 0) , сам скрипт тоже немедленно выходит по ошибке.
В данном случае, когда во всем скрипте всего то три команды, вместо 'set -e' можно поставить && после команд cd и scrot (результат будет идентичным).
Linux Firefox
0
0
andrewsh
Ещё лучше — просто указать в качестве параметра штуку вроде ~/my/screen/shots/%Y-%m-%d_\$wx\$h.png
Mac Safari
0
0
braintunic
Только при таком имени сохранится за день лишь один последний скриншот того-же размера, а предыдущие удалятся.
Надо либо добавить в таймстамп час-минуту-секунду (что просто), либо автоматически добавлять к имени порядковый номер (что чуть сложнее).
Linux Firefox
 Москва
0
0
Леонит Каганофф
[lleo@lleo]$ scrot -u
scrot: invalid option -- 'u'
Linux Firefox
0
0
phmagic
Этот человек не загрузил свой юзерпик, и я подобрал ему этот. Человек, пишущий такое, должен именно так выглядеть, верно?
Вообще-то xfce4-screenshooter умеет без диалогов (для этого есть опция -o). Но он медленный.

>time xfce4-screenshooter -o /bin/true -f

real 0m0.872s
user 0m0.737s
sys 0m0.063s

Это для экрана 3200х1200 на стареньком 285 @2.6GHz.
Linux Firefox
0
0
andrewsh
Ну ведь scrot -u ведь
Linux Firefox
 Москва
0
0
Леонит Каганофф
[lleo@lleo]$ scrot -u
scrot: invalid option -- 'u'
Mac Safari
0
0
braintunic
Установи scrot версию поновее.
http://mylinuxbook.com/scrot-command/
Linux Firefox
 Пенза
0
0
m1kc
Этот человек не загрузил свой юзерпик, и я подобрал ему этот. Человек, пишущий такое, должен именно так выглядеть, верно?
Дичайше рекомендую ScreenCloud. http://screencloud.net/

Она делает именно то, что обещает: нажал на кнопку - скриншот залился куда надо. Хоть в файл, хоть на FTP, хоть в облако, хоть в Dropbox. А ещё имя файла сразу копируется в буфер обмена.
Linux Firefox
0
0
Alex
Этот человек не загрузил свой юзерпик, и я подобрал ему этот. Человек, пишущий такое, должен именно так выглядеть, верно?
Хороший олдскульный скрипт, спасибо.
На моем Ubuntu он работает почти со всеми окнами, кроме одного - xterm.
При попытке запуска из xterm, xwdtopnm выдает вот такую вот ошибку:

xwdtopnm: can't handle X11 pixmap_depth > 24
pnmtopng: EOF / read error reading magic number

Может кто-нибудь знает, в чем тут дело?
Спасибо
Linux Safari Chrome
0
0
Evgeny
Этот человек не загрузил свой юзерпик, и я подобрал ему этот. Человек, пишущий такое, должен именно так выглядеть, верно?
Ежели у кого

xprop -root 32x ' $0' _NET_ACTIVE_WINDOW | awk {'print $2'}

не работает (у меня не работает, говорит _NET_ACTIVE_WINDOW: not found.), то можно сделать

xdotool getwindowfocus | awk {'print $1'}
Linux Firefox
 Москва
0
0
Леонит Каганофф
О, работает. А зачем awk {'print $1'}? И без него выдает чисто номер.

PS: Кстати, а никто не пытался сделать бинарник, который бы просто брал указанный аргумент и не пришлось бы использовать по природе своей медленный интерпретатор awk?

Типа: `echo 'aaa bbb ccc' | argum 2` - и выдает 'bbb'

Сколько я встречаю этот awk в скриптах - так только чтобы выдрать один из аргументов.
Linux Safari Chrome
0
0
Evgeny
Этот человек не загрузил свой юзерпик, и я подобрал ему этот. Человек, пишущий такое, должен именно так выглядеть, верно?
Там, похоже, ещё и перевод строки, который всё ломает, потому и awk
Ещё можно как-нибудь так:
xdotool getwindowfocus | tr '\n' ' '
Linux Firefox
 Москва
0
0
Леонит Каганофф
У меня ничего не ломает почему-то.
Mac Safari
0
0
braintunic
Нет никакой проблемы написать, скажем на Си, эмуляцию этой функциональности awk.
Правда выйдет это где-то 30-40 строк кода на Си, и боюсь, что быстрее "медленного по своей природе awk" оно будет работать только с файлами где-нибудь в полмиллиона и более строк, а с меньшими файлами разница во времени обработки будет совершенно несущественна (типа 0.1 секунды против 0.2 секунды полного времени обработки на файл в полмиллиона строк).
Windows Firefox
 Израиль
0
0
braintunic
Но если вопрос лишь в том, чтобы иметь такую утилитку argum для экономии тыканья клавиш, то вот пожалуйста:

#!/bin/sh
# argum <n> [file...] - print the given column from the given files(s) or from stdin
n=$1; shift
exec awk '{print $'$n'}' "$@"
Linux Firefox
0
0
Михаил
Этот человек не загрузил свой юзерпик, и я подобрал ему этот. Человек, пишущий такое, должен именно так выглядеть, верно?
#!/bin/sh
eval echo -n \${$(($1 + 1))}

Типа: "argum 2 aaa bbb ccc" выдаёт "bbb".
Windows Firefox
0
0
braintunic
Нет, ведь ваш скрипт решает совсем другую задачу, не ту, что поставил Лео.
Лео хочет взять любую строку со стандартного ввода и в результате обработки напечатать указанное поле (колонку), то есть, именно то, что делает awk '{print N}'.
(наверное использованный Лео термин "аргумент" вводит в заблуждение)

Ваш скрипт может делать то, что нужно Лео, но только вот так:
echo "aa bbb ccc" | xargs -l1 argum 2
но в таком случае нет никакой экономии по сравнению с прямым использованием awk '{print $2}'
Кстати, -n в вашем скрипте по-моему не нужен.
Linux Firefox
0
0
Михаил
Этот человек не загрузил свой юзерпик, и я подобрал ему этот. Человек, пишущий такое, должен именно так выглядеть, верно?
Насколько я понял, Лео просто хотел выкусить n-ое слово из вывода другой программы, и это можно сделать прямо через подстановку:

argnum 5 `date -R`

(выдаст время).

Но если хочется именно со стандартным вводом, то можно так:

#!/bin/sh
read a1 a2 a3 a4 a5 a6 a7 a8 a9 a10
eval echo -n \$a$1

Правда, количество "аргументов" будет ограничено.

Или путём вариации "параметрического" подхода:

#!/bin/sh
read a
eval set -- $1 $a
eval echo -n \${$(($1 + 2))}

Разница в том, что с "параметрами" можно использовать "закавыченные аргументы", а read (в первом случае) и awk просто бьют по пробелам.

> Кстати, -n в вашем скрипте по-моему не нужен.

echo без "-n" всё-таки добавляет перевод строки. Это может быть не всегда важно, но "чистый" результат более универсален.
Mac Safari
0
0
braintunic
Вариант с подстановкой не сумеет обработать многострочный ввод.
По большому счету, еще есть что обсуждать, но боюсь кроме нас двоих это никому здесь не интересно ;)
Linux Firefox
0
0
Михаил
Этот человек не загрузил свой юзерпик, и я подобрал ему этот. Человек, пишущий такое, должен именно так выглядеть, верно?
Может, вместо awk проще
... '\n$0' _NET_ACTIVE_WINDOW | tail -1
использовать? ;-)
Windows Firefox
0
0
gotar
Этот человек не загрузил свой юзерпик, и я подобрал ему этот. Человек, пишущий такое, должен именно так выглядеть, верно?
man cut ?

всего комментариев: 45

<< предыдущая заметка следующая заметка >>