Telegram CLI - обёртка для демона под zsh
В предыдщуей статье мы закончили на запуске демона и поняли, что посылать команды через конвеер не очень удобно. Поэтому сейчас мы будем писать оболочку для этого добра.
Коротко о zsh
Если вы всё ещё используете bash
, то пришло время поменять его на zsh
. Так надо.
Функция или отдельный файл?
Кому как удобнее; можете создать файл где-нибудь в путях и писать функционал в нём. Лично я храню все функции кучей в ~/.zshrc
. Поэтому описывать буду именно работу с функцией.
Для начала напишем простейшую оболочку:
function tcli () {
if [ $# -lt 1 ]; then
nc localhost 7313
return 0
fi
echo "$@" | nc localhost 7313
}
Не забываем перезайти в zsh, чтобы изменения вступили в силу!
Тут всё просто: если аргументов нет, то подключаемся к демону, если есть, то посылаем их на демона. Пробуем:
tcli help
Получаем:
Проблемы?
Молчание было ей ответом
Да, тут есть пара проблем. Одну из них вы заметите, когда попробуете написать какую-нибудь команду, от которой ответ придёт не моментально. Например, dialog_list
. Netcat отправит команду и тут же закроет соединение, не дождавшись ответа. Печально.
Тут и здесь люди предлагали разные варианты, но тот единственный метод, который сработал у меня, кажется костыльным, но работает.
Мы будем слать команду на демона через netcat и будем ждать пол секунды, чтобы получить ответ. Так себе решение, если у вас есть вариант лучше, feel free запостить его в комменты, буду благодарен!
Изменим часть с echo на такую:
(echo "$@"; sleep 0.5) | nc localhost 7313
Теперь dialog_list
радостно отвечает нам списком диалогов! А потом жадно жрёт процессорное время ещё треть секунды - какое расточительство!
Абсолютная и относительная власть
Пришло время раскрыть мой изначальный замысел. Зачем вообще это всё нужно, если есть замечательный клиент телеграма? Дело в том, что иногда мне по долгу службы приходится отправлять коллегам всякие там дампы и, так как всё общение у нас идёт в телеграме, то и файлы я отсылаю через него. Что мне приходилось делать раньше, чтобы скинуть дамп?
- Открыть терминал
- tar‘нуть или mysqldump‘нуть что-нибудь
- Запустить клиент Telegram‘a
- Открыть Nautilus
- Переместить руку с клавиатуры на мышку
- Найти нужный файл в проводнике
- Схватить его мышкой
- Alt+TAB‘нуться на Telegram
- Перетащить файл на нужный контакт
Одним словом - жуть! Использовать мышку и аж две гуишные программы, а так не хочется покидать консоль для такого простого действия.
Как я делаю это сейчас?
- Открываю терминал
- Делаю дамп
- tcli send_file КОНТАКТ ФАЙЛ
Но с существующей обёрткой у нас так пока сделать не получится, ещё не поняли почему?
Про власть в заголовке было так, для красивого словца, на самом деле здесь речь пойдёт о путях. Наш демон работает из /opt/tg/bin
, а рабочая директория терминала у нас может быть где угодно, поэтому когда мы хотим отправить файл, telegram-cli
будет искать его относительно своего bin
‘a, а не относительно пути из нашего терминала.
Конечно, можно каждый раз скармливать ему абсолютный пусть до отправляемого файла, но мы тут говорим об удобстве, а добавлять `pwd`
к файлу это не то что не очень удобно, это очень неудобно. Проблему надо как-то решать! Запаситесь костылями терпением, остался последний рывок.
Вставим в нашу функцию такой кусок:
tmpargs=()
for var in "$@";do
if [[ -f $var ]]; then
var=`realpath $var`
fi
tmpargs+=($var)
done
Что мы тут делаем: сначала пробегаемся по аргументам и смотрим, что из них, и есть ли в них вообще, имена файлов, далее получим полный путь до этих файлов и уже в таком виде скормим это демону.
Может возникнуть коллизия, есть вы хотите отправить что-то человеку, имя которого совпадает с именем файла в рабочей директории, но я стараюсь не давать человеческие имена файлам, поэтому у меня проблем не возникает.
Как изменять аргументы напрямую в массиве переданных аргументов я не знаю(если вы знаете как, то welcom в комменты), поэтому мы создадим временный массив, в которым будет результирующий массив; он же и пойдёт к демону.
Итоговая функция теперь выглядит так:
function tcli () {
if [ $# -lt 1 ]; then
nc localhost 7313
return 0
fi
tmpargs=()
for var in "$@"; do
if [[ -f $var ]]; then
var=`realpath $var`
fi
tmpargs+=($var)
done
(echo "$tmpargs"; sleep 0.5) | nc localhost 7313
}
Вот и всё, теперь можно отправлять файлы через терминал с удовольствием! А если долго не смотреть на эту функцию, то можно забыть про все ужасы костыльной реализации и радоваться.
Это всё?
На сегодня хватит. Я думал здесь же написать про автодополнение по tab
‘у, но статья и так получилось массивной, так что об этом в следующий раз.
Спасибо, что читаете!