Скоротити URL із термінала можна одним рядком:
curl -s -X POST https://api.elido.app/v1/links \
-H "Authorization: Bearer $ELIDO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"destination_url":"https://example.com/spring-sale"}' | jq -r .short_url
Ця команда виводить https://s.elido.me/ab12cd і нічого більше. curl надсилає запит, jq витягує одне поле з JSON, а -r прибирає зовнішні лапки, щоб значення можна було одразу передати в буфер обміну або іншу команду.
Решта цієї статті присвячена чотирьом удосконаленням, які перетворюють цей рядок на інструмент, яким справді користуєшся: функції оболонки, коректним кодам завершення, масовій обробці з обмеженою паралельністю та буферу обміну. Якщо вам зручніше писати мовою програмування, а не мовою оболонки, такий самий виклик є у Python, Go і ще шести середовищах виконання.
Перетворіть це на команду
Псевдонім не може приймати аргумент, тому використайте функцію. У .zshrc або .bashrc:
short() {
[ -z "$1" ] && { echo "usage: short <url> [slug]" >&2; return 2; }
local body
body=$(jq -n --arg url "$1" --arg slug "${2:-}" \
'{destination_url: $url} + (if $slug == "" then {} else {slug: $slug} end)')
curl -s --fail-with-body -X POST https://api.elido.app/v1/links \
-H "Authorization: Bearer $ELIDO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(printf %s "$1" | shasum -a 256 | cut -d' ' -f1)" \
-d "$body" | jq -r .short_url
}
У цьому коді є три свідомі рішення.
Побудова JSON за допомогою jq -n --arg, а не інтерполяції рядків, означає, що адреса призначення з лапкою або амперсандом не зламає запит. Це оболонковий еквівалент параметризованого SQL, і пропуск цього кроку створює той самий клас помилок.
--fail-with-body - прапорець, про який часто забувають. За замовчуванням curl завершується з кодом 0 після будь-якого завершеного обміну, тому відповідь 401 проходить конвеєр, jq виводить null, а скрипт продовжує роботу з null там, де мало бути посилання. З цим прапорцем відповідь 4xx встановлює ненульовий статус завершення, і ви все одно отримуєте тіло помилки для перегляду.
Idempotency-Key, отриманий з URL, означає, що повторний запуск тієї самої команди повертає те саме посилання, а не створює два. Це ще важливіше в розділі про масову обробку нижче, а пояснення наведено в матеріалі про ліміти запитів та ідемпотентність.
Потрібен ключ? Створіть його на безкоштовному плані, експортуйте з профілю оболонки, і функція працюватиме в наступному новому терміналі.
Одразу в буфер обміну
Останні кілька символів, завдяки яким усе здається завершеним:
short "https://example.com/spring-sale" | tee /dev/tty | pbcopy # macOS
short "https://example.com/spring-sale" | tee /dev/tty | xclip -sel c # Linux, X11
short "https://example.com/spring-sale" | tee /dev/tty | wl-copy # Wayland
short "https://example.com/spring-sale" | tee /dev/tty | clip.exe # WSL
tee /dev/tty одночасно виводить посилання й копіює його, тож це зручніше, ніж копіювати навмання й сподіватися на результат.
Масова обробка без накопичення 429
Файл із URL, які скорочуються по вісім за раз:
export -f short # bash; zsh users call the script directly
xargs -P 8 -I{} bash -c 'short "{}"' < urls.txt > short-urls.txt
-P 8 - уся стратегія роботи з лімітом: одночасно виконується вісім запитів незалежно від того, містить файл п'ятдесят рядків чи п'ятдесят тисяч. Без цього xargs запускає процеси з максимально можливою швидкістю, і API відповідає 429 на більшість запитів.
Перед передаванням справжнього файлу варто знати про два нюанси. xargs -P перемішує вивід, тому рядки можуть прийти не в тому порядку; якщо відповідність між входом і виходом важлива, виводьте обидва значення:
xargs -P 8 -I{} bash -c 'printf "%s\t%s\n" "{}" "$(short "{}")"' < urls.txt > mapping.tsv
А URL, що містить пробіл або лапку, не переживе -I{} без екранування. Для будь-яких даних, наданих користувачем, безпечним варіантом буде xargs -0 із файлом, де записи розділені нульовим байтом. На цьому етапі написати справжній скрипт на Python зазвичай простіше, ніж правильно налаштувати лапки.
Не залишайте ключ в історії
ELIDO_API_KEY=abc123 short <url> записує ключ у ~/.zsh_history і список процесів, де його зможе прочитати будь-який інший обліковий запис на комп'ютері за допомогою ps.
Експортуйте ключ із профілю оболонки або, ще краще, отримуйте його зі сховища секретів під час запуску оболонки:
export ELIDO_API_KEY="$(security find-generic-password -s elido -w)" # macOS Keychain
export ELIDO_API_KEY="$(pass show elido/api-key)" # pass
Тоді для ротації ключа достатньо оновити один запис, а не шукати його в прихованих файлах на трьох комп'ютерах. Той самий принцип діє на серверній стороні будь-якого запланованого скрипту, а вебхуки для подій посилань показують підхід до отримання даних без зберігання ще одного ключа десь у системі.
Коли термінал є правильним місцем
Термінал підходить, коли URL уже є у файлі, ви вже працюєте в оболонці або скорочення є одним із кроків більшого скрипту: процес випуску, який генерує посилання на дистрибутив, завдання CI, що скорочує URL розгортання попереднього перегляду, або git-хук, який створює посилання для запису в журналі змін.
Термінал не підходить для керування кампанією. Для папок, тегів і порівняння кількості кліків у різних місцях розміщення потрібен дашборд, а спроба робити це за допомогою запитів jq до кінцевої точки списку перетворюється на окремий проєкт, а не на швидке рішення. У розділі рішення для розробників описано можливості API за межами створення, а в матеріалі про API та SDK розглянуто типізовані клієнти на випадок, коли скрипту оболонки вже недостатньо.
Читайте основну серію
Ця стаття входить до інженерного кластера. Почніть із посібника з безкоштовного API сервісу скорочення URL, щоб ознайомитися зі структурою кінцевої точки, а потім прочитайте про ліміти запитів та ідемпотентність. Актуальна довідка доступна в документації API.
Пов'язані статті в блозі
Поширені запитання
Як скоротити URL із командного рядка?
Надішліть адресу призначення до API сервісу скорочення через curl і передайте відповідь у jq, щоб витягнути коротке посилання. Один рядок, нічого не потрібно встановлювати, крім curl і jq, а ключ API надходить зі змінної середовища, тому ніколи не з'являється в історії оболонки.
Як перетворити це на команду для повторного використання?
Огорніть виклик curl у функцію оболонки у вашому .zshrc або .bashrc, передаючи URL як перший аргумент. Перезавантажте профіль, і short https://example.com працюватиме з будь-якого каталогу. Тут функція краща за псевдонім, тому що їй потрібно приймати аргумент.
Чому мій конвеєр curl завершується успішно, якщо API повернув 401?
Тому що curl завершується з кодом 0 після будь-якого завершеного обміну HTTP, зокрема після відповіді з помилкою. Додайте --fail-with-body, щоб для відповіді 4xx або 5xx встановлювався ненульовий код завершення, а тіло все одно виводилося. Інакше скрипт продовжить роботу з об'єктом помилки там, де мало бути коротке посилання.
Як скоротити цілий файл URL з оболонки?
Передайте файл у xargs із параметром -P 8, щоб одночасно виконувати вісім запитів, і -I{}, щоб підставляти кожен рядок. Це обмежує паралельність вісьмома запитами незалежно від довжини файлу, завдяки чому великий пакет не перевищує ліміт API і не накопичує відповіді 429.
Як скопіювати коротке посилання безпосередньо в буфер обміну?
Передайте результат у pbcopy на macOS, xclip -selection clipboard у Linux з X11, wl-copy у Wayland або clip.exe у WSL. Разом із функцією оболонки це означає, що одна команда створює посилання, уже готове до вставлення.
Де зберігати ключ API для роботи з CLI?
У змінній середовища, експортованій із профілю оболонки, або, ще краще, отримувати його під час запуску оболонки з менеджера паролів чи сховища секретів. Якщо ввести ключ безпосередньо в команду, він потрапить у файл історії та список процесів, де його зможе прочитати будь-який інший користувач комп'ютера.
Спробуйте Elido
Вставте URL - отримайте коротке посилання
Без реєстрації. Посилання живе 30 днів. Зареєструйтесь, щоб зберегти назавжди.
Безкоштовно, без реєстрації · 2 на день