LINUX.ORG.RU

тупой вопрос по js и bash

 , ,


1

1

Здравствуйте.

Вот у меня firefox с Tampermonkey, которая умеет исполнять пользовательские скрипты. Действует это, по моему слабому пониманию, примерно так: документ загрузился -> js-скрипт получил отмашку выполниться.

Вопрос в следующем: я могу как-то в этом скрипте вызвать «обычную консольную системную» команду? Чтоб в конечном итоге было так: документ загрузился -> *что-то там такое* -> команда исполнилась.

Прочёл то, что написал - да, это выглядит диковато. Буду рад немножко продвинуться по тематике. Спасибо за внимание.

★★★★★

Напрямую - нет, это совершенно изолированные среды.

Но можно выполнить удалённый запрос из юзерскрипта (GM_xmlhttpRequest) на какой-нибудь вебсервис, который это поддерживает, или написать такой самому, например, на bottle.py

E ★★★
()

Для такого тамперу нужна прога-посредник на стороне системы, тогда он мог бы слать ей команды через Native messaging, а она отправлять их в консоль. Но вряд ли в нем это запилили.

mydibyje ★★★★
()
Последнее исправление: mydibyje (всего исправлений: 2)

Современный браузер — изолированная среда. Оттуда нельзя пулять команды. Это тебе не Internet Explorer.

Но это часто обходят, написав программу, которая будет слушать на локалхосте REST-запросы. Такое можно на пистоне и fastapi накалякать за пару часов по гайдам. Или на ноде с express.js, если прям хочется жабаскрипт.

Можно попробовать поискать готовый опенсорцный сервис для вебхуков. В котором можно создавать ссылки, по которым если переходят, выполняется определённая команда или код. И опять же запустить на локалхосте через systemd user сервис.

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

Кажется самым логичным и экологичным. Спасибо! Курю маны по inetutils-inetd.

Не можешь кинуть пример js-строчки, «дёргающей» какой-нибудь inetd-юнит?

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

Не можешь кинуть пример js-строчки, «дёргающей» какой-нибудь inetd-юнит?

Copilot:

// URL эндпоинта
const url = 'https://api.example.com/data';

// Опции запроса
const options = {
method: 'GET', // или 'POST', 'PUT', 'DELETE' в зависимости от вашего запроса
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_ACCESS_TOKEN' // если требуется авторизация
}
};

// Выполнение запроса
fetch(url, options)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
return response.json();
})
.then(data => {
console.log(data); // Обработка данных
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});

ЧатЖопатэ:

async function sendRequest() {
  const url = 'https://example.com/api/endpoint';  // Замените на ваш эндпоинт
  const data = {
    key1: 'value1',
    key2: 'value2'
  };

  try {
    const response = await fetch(url, {
      method: 'POST', // Можно поменять на 'GET', 'PUT', 'DELETE' в зависимости от типа запроса
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data)  // Если метод GET, body не нужен
    });

    if (!response.ok) {
      throw new Error(`Ошибка HTTP: ${response.status}`);
    }

    const result = await response.json();  // Если ответ в формате JSON
    console.log('Ответ сервера:', result);
  } catch (error) {
    console.error('Ошибка запроса:', error);
  }
}

// Вызов функции
sendRequest();
iron ★★★★★
()
Ответ на: комментарий от iron

Как вариант, слушать сокет через [x]inetd, который будет перенаправлять данные твоему скрипту. Тогда дергаешь этот эндпоинт из js и скрипт выполняет то что нужно.

Но вот только [x]inetd решает только часть задачи: слушать TCP-сокет и вызвать программу-обработчик. А реализация HTTP остаётся на совести самого обработчика. Так что проще взять какую-то готовую реализацию HTTP-сервера, который будет и слушать, и парсить. Ну или, как вариант, WebSoсket-сервера.

annulen ★★★★★
()

Обычно для такого собственные расширения пишут. Но как выше написали, если что-то на коленке собрать, то вариант с локальным сервером вполне подойдёт. Минус в том, что любой другой юзерскрипт потенциально тоже может запускать через этот сервер команды.

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

А реализация HTTP остаётся на совести самого обработчика.

А ТС-у, исходя из его ТЗ, http там нафиг не нужен. Как только придет коннект на порт – inetd выполнит нужный скрипт. А в скрипте можно всего лишь просто инициализировать подключение к сокету.

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

И правда. Главное, чтобы ТС потом не удивлялся, почему его запрос всё время приводит к ошибке (с точки зрения js-кода), почему нельзя передать никакие параметры и ничего получить в ответ.

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

почему нельзя передать никакие параметры и ничего получить в ответ

В ответ inetd отправит stdout скрипта. Если его вывод немного причесать, то можно парсить со стороны js (если в этом есть необходимость).

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

Для локального сервиса это будет http://127.0.0.1:[port]

Я с js совсем не знаком. А там можно указать урл по пипу: socket://127.0.0.1:4000? Тогда не будет отправлять ненужные http хедеры.

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

Я делал для таких вещей локальный хттп сервер, настраивал на нём cors, чтобы браузер не ругался и потом fetch или ajax запрос на локалхост.

Если взять готовый HTTP-сервер с поддержкой CGI и возможностью настройки хедеров в ответе, то это крутой вариант, так как можно писать простые скриптики-обработчики на любом ЯП, не думая о веб-вещах. А если без CGI, то тогда уже лучше на каком-нибудь микрофреймворке писать, или даже простенькой библиотеке для создания HTTP-сервера вроде перлового HTTP::Daemon

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

где port — это порт, который настроен в inetd

вот что мне интернет говорит о строчке из /etc/inetd.conf:

service-name socket-type protocol {wait|nowait}[/max-child[/max-connections-per-ip-per-minute[/max-child-per-ip]]] user[:group][/login-class] server-program server-program-arguments

Я не вижу, где здесь порт. Сорри за тупизну ещё раз - тема для меня совсем новая...

piyavking ★★★★★
() автор топика

Ну браузер же не позволит локальные команды запускать. А так-то для себя можно поднять локальный веб-сервер, который по запросу из js-файла что угодно запустит.

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

Я не вижу, где здесь порт

Он зашит в service-name, список которых находится в /etc/services. Если я правильно понимаю, на каждый порт придётся придумывать имя сервиса и добавлять туда.

В качестве альтернативы можно использовать systemd, в котором не нужно править /etc/services и придумывать имя протокола (но придётся придумать имя для юнит-файла). Вот руководство: http://0pointer.de/blog/projects/inetd.html.

annulen ★★★★★
()