LINUX.ORG.RU

Запускатор программ/открыватор файлов на bash/zsh

 , ,


0

3

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

Пока сделал так:

cat .zshrc

xo () {
xdg-open $1 &
disown
exit
}

xr () {
$1 &
disown
exit
}
По специальному сочетанию клавиш открывается терминал 100x5 столбцов, по команде

xo ФАЙЛ

Файл открывается через xdg-open, окошко терминала уходит

По команде

xr команда

Выполняется команда, окошко терминала уходит.

Вроде, всё неплохо, но некоторые вещи далеки от идеала:

1.) Если вызываю xo (ожидается имя файла), то автодополнение zsh работает, как надо - предлагает имя файла. При этом, если я вызываю xr, мне надо, чтобы автодополнение предлагало пути из $PATH (как если бы я не вызывал xr, а просто набрал первую букву имени проги и жал Tab), однако, оно предлагает по-прежнему автодополнять пути (что ожидаемо, ведь оно считает, что xr - команда, а её аргумент - файл). Как бы мне сделать так, чтобы автодополнение после xr предлагало команды, а не файлы?

2.) Можно ли сделать так, чтобы по-умолчанию любая вводимая команда выполнялась так, как если бы она была аргументом функции xr? То есть, я себе вижу это так: я ввожу какую-то команду, как если бы речь шла об обычном zsh/bash без каких-либо функций (автодополнение работает, как обычно), жму enter - она выполняется с отвязкой от shell, shell закрывается. Либо же я могу ввести xo ФАЙЛ и он откроется так, как полагается с учётом той функции xo.

Буду очень благодарен за все советы.

★★

Последнее исправление: Valdor (всего исправлений: 1)
Ответ на: комментарий от Valdor

Чёт немного мне принцип непонятен. Может лучше сделать проверку на не существование файла, потом проверку на то, расположен ли он в PATH, затем на права для исполнения, а потом уже xdg-open. Т.е (баш на уровне программирования не очень знаю, так что реализуешь сам):

если файл не существует, тогда echo "файл не существует" && sleep 2 && clear
иначе,
если файл есть в $PATH, то запустить файл 
иначе,
если файл имеет права на запуск, спроисть "Запустить или открыть?"
запустить или открыть
иначе,
открыть файл

sudopacman ★★★★★
()
Ответ на: комментарий от sudopacman

Я так рассуждал - Если файл не существует, то либо пользователь указал не то, либо это - команда из PATH. Тогда мы её выполним. Если не получилось - пользователь ошибся, делать нечего.

Если же файл существует, то если он исполняемый - исполним, иначе — откроем.

Пожалуй, единственное, что надо еще обработать - случай, когда файл назван по имени, и он есть и в текущем каталоге, и в PATH.

Твое предложение рухнет на этапе проверки, есть ли файл, ведь придётся весь PATH проверять, иначе останемся вообще без его содержимого.

А вопрос «исполнить или открыть» - косметическая мелочь, запилить легко.

Valdor ★★
() автор топика
Последнее исправление: Valdor (всего исправлений: 2)
Ответ на: комментарий от sudopacman

Переработал. На свежий мозг мне твой вариант показался более правильным:

#!/bin/bash
if [ `compgen -c | grep -x "$1"` ]
then
	echo "Файл находится в PATH"
	$* &
	disown
elif [ -e "$1" ]
then
	echo "Файл существует по указанному пути"
	if [ -x "$1" ]
	then
		if [[ "$(dirname $1)" = "." ]]
		then
			echo "Файл находится в текущем каталоге"
			./$* &
			disown
		else
			$* &
			disown
		fi
	else
		xdg-open "$1" &
		disown
	fi
else
	echo "Такого файла нет ни по указанному пути, ни в PATH"
fi

Фишка такова. Допустим, какой-то объект есть и в PATH, и в текущем каталоге. Допустим, у меня в текущем каталоге лежит файл dd, имеющий права на исполнение. Если вызову

./script.sh dd

выполнится dd из PATH

Если же

./script.sh ./dd

выполнится местный dd.

Valdor ★★
() автор топика
Последнее исправление: Valdor (всего исправлений: 2)
Ответ на: комментарий от sudopacman

sudopacman, salsa

Итак, что-то есть. Вариант для включения в .zshrc: http://pastebin.com/pz7njM9p

Отдельный скрипт: http://pastebin.com/miUbtF25

В случае с .zshrc добавлено автодополнение (которое будет автодополнять всё именно так, как соответствует моей задумке), спасибо llua из IRC-чата #zsh на FreeNode за это.

Я использую exo-open для открытия файлов, можно спокойно заменить на xdg-open, gnome-open, kde-open, если сочтёте нужным. disown можно убрать (это отцепляет команду от терминала, чтобы можно было закрыть. Предполагается, что с помощью этой функции никто не будет запускать то, что требует интерактивного ввода на stdin).

Надо ещё подрихтовать, причесать и так далее, но, кажется, функциональная часть пашет. Если будет не лень - пообкатывайте, пожалуйста.

Valdor ★★
() автор топика
Ответ на: комментарий от sudopacman

Да нахрен не нужно, я с их помощью разбирался, почему результат оказывался не тем.

Эта вундервафля умеет открывать не только локальные файлы, но и http://, ftp:// (поскольку является обёрткой над xdg-open и прочими). Можно запилить обработку других типов команд (во-первых, через написание обработчиков протоколов для тех самых xdg-open, во-вторых, через различную реакцию на разный формат аргумента).

Valdor ★★
() автор топика
Последнее исправление: Valdor (всего исправлений: 1)
Ответ на: комментарий от sudopacman

Что ещё хочу замутить - отдельные опции, которые бы открывали набранное во внешнем терминале или принудительно обрабатывали объект, не как исполняемый (т.е. открывали).

Valdor ★★
() автор топика
Ответ на: комментарий от salsa

Слушай, а ты не в курсе, как переопределить стандартное автодополнение команд, когда еще ничего не введено? Хочу, чтобы вместо автодополнения команд (когда в пускать строку только начинает что то вводить) работало вот это новое _xo, и сделать так, чтобы перед каждой командой оно автоматом вставляллсь (метод описан выше)

Valdor ★★
() автор топика
Ответ на: комментарий от Valdor

Один вопрос: почему ты пишешь две версии — для bash и в виде функции для zsh? Можно просто положить bash- (или zsh-) скрипт в $PATH, и compdef _xo xo будет работать.

shdown
()
Ответ на: комментарий от shdown

У меня и так работает. Они одинаковые теперь. Я хочу теперь минимизировать необходимые действия для использования.

Valdor ★★
() автор топика
Ответ на: комментарий от Valdor

По дополнению не подскажу, думаю, с completer'ом что-то.

чтобы перед каждой командой оно автоматом вставляллсь

Можно через подмену виджета accept-line или с помощью хука preexec.

И предвидя твои будущие хотелки, глянь еще в сторону predict-on и https://github.com/tarruda/zsh-autosuggestions.

salsa
()
Ответ на: комментарий от Valdor

Тогда и файл автодополнения можно положить куда-нибудь в $fpath.

salsa
()
Ответ на: комментарий от shdown

О, это даже изящнее, чем то, о чем я подумал. Шикарно, спасибо огромное.

Valdor ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.