Перейти к главному содержимому

SSH через сервер

Для подключения одного ПК к другому по ssh через сервер (туннелирование) можно использовать следующую схему:

SSH via server diagram

(Рисунок сделан за 5 минут при помощи редактора yEd)

Создание туннеля

На ведомом ПК (к которому подключаются) надо установить соединение с сервером, при этом "пробросить" порт 1234 на сервере на свой порт 22, где запущен ssh-сервер (remote port forwarding).

ssh -R 1234:127.0.0.1:22 -N user@server

user - имя пользователя на сервере.

На ведущем ПК (который подключается) надо установить соединение с сервером, при этом "пробросить" локальный порт 1234 на серверный порт 1234 (local port forwarding).

ssh -L 1234:127.0.0.1:1234 -N user@server

user - имя пользователя на сервере (не обязательно такое же как и у ведомого).

Подключение по SSH через туннель

На ведущем ПК (который подключается) надо установить соединение с ведомым компьютером через туннель.

ssh -p 1234 userslave@127.0.0.1

userslave - имя пользователя на ведомом компьютере.

Происходит следующее:

  1. ssh подключается на свой адрес на порт 1234
  2. соединение туннелируется на сервер на порт 1234 (local forwarding)
  3. соединение туннелируется на ведомый компьютер на порт 22 (remote forwarding)

P. S. Ссылка не совсем по теме, но тоже интересно.

Разные полезности при работе с git

Разные полезности при работе с git

Шаблон файла для настройки .gitconfig

Работает и под windows.

Файл находится в "домашнем" каталоге пользователя. Под windows он (каталог) определяется переменной среды HOME или (если переменная не задана), то в зависимости от версии ОС C:\Users\username\ или C:\Documents and settings\username.

Под linux обычно это /home/username.

В домашнем каталоге следует создать подкаталог certs и положить туда файл с сертификатами ca-bundle.crt.

Файл настроек:

[core]
    editor = notepad.exe
    autocrlf = true
    whitespace = trailing-space,space-before-tab,indent-with-non-tab,cr-at-eol
    quotePath = false
    compression = 9
    commitGraph = true
[http]
    sslCAInfo = ~/certs/ca-bundle.crt
    sslCAPath = ~/certs
[alias]
    co = checkout
    ci = commit
    st = status
    br = branch
    hist = log --pretty=format:\"%h %ad | %s%d [%an]\" --graph --date=short
    sub = submodule update --init --recursive
    rd = branch -rd
    rr = branch -rd
    chmod = update-index --chmod=+x
[push]
    default = matching
[fetch]
    recurseSubmodules = true
    prune = true
[submodule]
    recurse = true
[sendpack]
    sideband = false
[user]
    name = unknown
    email = unknown@example.com

Переместить ветку git на другой коммит без вытаскивания

git branch -f master origin/master

git push во все remote

Файл gitpusha.bat для windows:

@rem # Если поместить этот файл в одну из директорий, прописанных в системной
@rem # переменной окружения PATH, то можно прямо из любого репозитория
@rem # вызывать gitpusha [parameters] что будет аналогично
@rem # запуску git push <remote-name> [parameters] последовательно для всех
@rem # заданных remote в текущем репозитории

git remote | xargs -l -t git push %*

Скрипт gitpusha для linux:

#!/bin/sh

git remote | xargs -l -t git push "$@"

Количество коммитов в git-репозитории

Статистика по пользователям
git shortlog --all -s -n
Просто общее количество
git rev-list --count --all
За период
git rev-list --count --since="Jan 1 2020"  --before="Dec 31 2020" --all

Инициализация сабмодулей по файлу .gitmodules

#!/bin/sh

set -e

git config -f .gitmodules --get-regexp '^submodule\..*\.path$' |
    while read path_key path
    do
        url_key=$(echo $path_key | sed 's/\.path/.url/')
        url=$(git config -f .gitmodules --get "$url_key")
        git submodule add $url $path
    done

Удаление недостижимых объектов из локального репозитория git

git reflog expire --expire-unreachable=now --all
git gc --prune=now
git fsck --unreachable --no-reflogs

Замена url для git

Если надо массово заменить URL для всех обращений к репозиториям (например, при работе через какой-либо прокси), то достаточно в глобальный .gitconfig или в config репозитория добавить что-то типа такого:

[url "ssh://git@127.0.0.1:2222/"]
    insteadOf = git@github.com:

Или, например, чтобы заменить все обращения по https на ssh:

[url "git@github.com:"]
    insteadOf = https://github.com/

Само собой, это можно сделать и командой:

git config --global url."git@github.com:".insteadOf https://github.com/

Установка имени пользователя и email для репозитория

#!/bin/sh

git config user.name myusername
git config user.email myemail@users.noreply.github.com

Настройка VLAN под Linux

Запускать под root-ом. В примере обычный интерфейс - eth0, а интерфейс с VLAN - eth0.5

Создание

# Create VLAN
# Команды выполнять под root-ом
# В этом примере создаётся интерфейс eth0.5, работающий через eth0 c 
# VLAN id = 5

ip link add link eth0 name eth0.5 type vlan id 5
ip link
ip -d link show eth0.5

ip addr add 192.168.1.200/24 brd 192.168.1.255 dev eth0.5
ip link set dev eth0.5 up

Удаление

# Delete VLAN

ip link set dev eth0.5 down
ip link delete eth0.5

Запуск http-сервера на python

Чтобы просто расшарить папку можно запустить в ней простой http-server. По умолчанию сервер запускается на порту 8000.

python -m http.server [port]

Если python имеет исполняемый файл python3, то его и надо вписать в скрипт:

python3 -m http.server [port]

ffmpeg tips

FFMPEG tips

выдрать звук и сохранить в mp3 с высшим качеством

ffmpeg -i inputfile -q:a 0 outputfile.mp3

Масштабирование

Без сохранения aspect ratio

ffmpeg -i complex.mov -crf 20 -vf scale=640:360 complex-small.mp4

С сохранением aspect ratio

ffmpeg -i input.jpg -vf scale=320:-1 output_320.png

Some codecs require the size of width and height to be кратны n. Для этого в качестве высоты надо установить -n.

ffmpeg -i input.jpg -vf scale=320:-2 output_320.png

Подробней про хитрое масштабирование.

concat files

ffmpeg -f concat -i mylist.txt -c copy complex.mov

mylist.txt:

file filename1
#comment
file filename2
....

speedup without sound

ffmpeg -i o1-20.mp4 -an -filter:v "setpts=0.25*PTS" o-fast.mp4

ffmpeg -i complex-small.mp4  -movflags +faststart -pix_fmt yuv420p -crf 20 -an -filter:v "setpts=0.2*PTS" complex-fast.mp4

speedup with sound

ffmpeg -i complex-small.mp4  -movflags +faststart -pix_fmt yuv420p -crf 20  -filter_complex "[0:v]setpts=0.125*PTS[v];[0:a]atempo=2.0,atempo=2.0,atempo=2.0[a]" -map "[v]" -map "[a]" compex-fast-big.mp4

crop

Use the crop filter:

ffmpeg -i in.mp4 -filter:v "crop=out_w:out_h:x:y" out.mp4

To crop a 80x60 section, starting from position (200, 100):

ffmpeg -i in.mp4 -filter:v "crop=80:60:200:100" -c:a copy out.mp4

The audio is stream copied in this example, so re-encoding is avoided.

To crop the bottom right quarter:

ffmpeg -i in.mp4 -filter:v "crop=in_w/2:in_h/2:in_w/2:in_h/2" -c:a copy out.mp4

This is the same as:

ffmpeg -i in.mp4 -filter:v "crop=320/2:240/2:320/2:240/2" -c:a copy out.mp4

Which is the same as:

ffmpeg -i in.mp4 -filter:v "crop=240:120:240:120" -c:a copy out.mp4

You can refer to the input image size with in_w and in_h as shown in this first example. The output width and height can also be used with out_w and out_h.

Crop 20 pixels from the top, and 20 from the bottom:

ffmpeg -i in.mp4 -filter:v "crop=in_w:in_h-40" -c:a copy out.mp4

The filter will automatically center the crop if x and y are omitted such as in this example.

Preview:

ffplay -i input -vf "crop=in_w:in_h-40"

Яркость/контраст/гамма/насыщенность

ffmpeg -i in.mp4 -vf eq=gamma=0.5:saturation=0.3 -crf 5 -y out.mp4

crop и сохранение в animated gif

ffmpeg -i in.mp4 -filter:v "crop=300:800:200:-400" -pix_fmt rgb24 -r 10 -y tower1.gif

Сохранение в webm для стикеров telegram

Надо constant quality, не constrained, поэтому -b:v 0.

ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 output.webm

Ещё вариант с масштабом жестким без сохранения aspect ratio:

ffmpeg -i input_file.mp4 -framerate 30 -c:v libvpx-vp9 -an -vf scale=512:512 -pix_fmt yuva420p output_sticker.webm

cut

ffmpeg -i input.wmv -ss 00:00:30.0 -c copy -t 00:00:10.0 output.wmv
ffmpeg -i input.wmv -ss 30 -c copy -t 10 output.wmv

ffmpeg -i input.mp4 -ss 30 -to 40 output.mp4

You can also put -ss before -i !!!

The -t option doesn't work for short videos, but it does for longer videos. For short videos it seems that -frames:v is better. This is what worked for me.

ffmpeg -ss 4 -i input.mp4 -frames:v 200 -vcodec copy -acodec copy output.mp4

For me -t option didn't work, but -vframes worked. I prefer using #frames, since I would rather cut at I-Frames and I found out GOP for video using ffprobe.

The command line that worked for me is:

ffmpeg -ss 60s -i input.wmv -vframes 1800 -acodec copy -vcodec copy output.wmv

By the way, putting -ss in the front of -i makes a big difference in execution time.

Inaccurate seek:

ffmpeg -noaccurate_seek -ss 120 -i input.mp4 -y -vcodec copy -acodec copy -to 8 -avoid_negative_ts make_zero output.mp4

For browser

ffmpeg -i input_file -q:v 4 -q:a 7 -movflags +faststart -pix_fmt yuv420p -acodec libvorbis -vcodec libtheora output.ogv

After that create html file:

<html><body>

<h2>TITLE</h2>

<video width="1024" height="576" controls="controls">
<source src="output.ogv" type='video/ogg; codecs="theora, vorbis"'>
  Тег video не поддерживается вашим браузером.
</video>
<br><br>
</body></html>

Генерация сигналов

ffmpeg -f lavfi -i "sine=frequency=1000:sample_rate=48000:duration=5" -af "volume=-6dB" -c:a pcm_s16le test.wav

Установка TeXLive в Debian

Install texlive.

apt install latexmk texlive-science texlive-lang-cyrillic \
 texlive-font-utils texlive-music latexdiff python3-matplotlib \
 texlive-generic-extra texlive-games cm-super texlive-fonts-extra

Install pscyr

tlmgr init-usertree
tlmgr install --file pscyr.tar.xz
updmap-user

sudo updmap-sys

Install additional utils

apt install optipng python3-pygments

Установка пакета в latex

tlmgr install --verify-repo=none <package name>

# установка из файла
tlmgr install --file <filename>

Chromium proxy

Запуск Chromium через заданный прокси

#!/bin/bash

chromium --proxy-server="socks5://127.0.0.1:8080" &

Запуск Chromium через автоматическую настройку прокси

#!/bin/bash

chromium --profile-directory=Default --proxy-pac-url="<wpad url>" &

Запуск Chromium через sock5-прокси, созданный через ssh

Запуск ssh на нужный сервер с прокси на порту 1080, без интерактивной консоли.

ssh -2TnN -D 1080 user@domain.com

ssh умеет ещё и сжимать трафик, подавлять сообщения (ключи -C -q).

Оставляем сеанс ssh запущенным.

Запуск chrome (может не сработать, смотря какая версия).

chrome --proxy-server="socks5://127.0.0.1:1080" --host-resolver-rules="MAP * ~NOTFOUND , EXCLUDE 127.0.0.1"

Другой вариант запуска chrome с новым профилем (каталог профиля может быть другим, естественно):

chrome --proxy-server="socks5://127.0.0.1:1080" --user-data-dir="~/.config/chromeproxy-profile"

Для проверки внутри chrome в адресную строку пишем (НЕ РАБОТАЕТ - показывает пустой экран):

chrome://net-internals/#proxy

Страница с перечнем служебных страниц:

chrome://about

Там есть интересные штуки, например, список usb-устройств )):

chrome://usb-internals

Скрипты для PulseAudio через jack

Установка

Для работы нужен модуль pulseaudio-module-jack. Для его установки:

apt install pulseaudio-module-jack

Приостановка PulseAudio

Для отключения PulseAudio на время работы программы есть команда:

pasuspend -- <some program> [parameters]

Эту команду можно добавить префиксом к jackd

Включение PulseAudio через jack

#!/bin/sh

pactl load-module module-jack-sink channels=2; pactl load-module module-jack-source channels=2; pacmd set-default-sink jack_out

Отключение PulseAudio через jack

#!/bin/sh

pacmd unload-module module-jack-source; pacmd unload-module module-jack-sink

Listing test

cyclic_buffer.c (Источник)

#include <stdint.h>
#ifndef XX_BUF_SIZE_BITS
/* по умолчанию размер буфера 2**5 = 32 */
#define XX_BUF_SIZE_BITS   5U
#endif
#define XX_BUF_SIZE       (1U<<(XX_BUF_SIZE_BITS))
#define XX_BUF_SIZE_MASK  ((XX_BUF_SIZE)-1U)
static uint8_t xx_buf[BUF_SIZE] = {0};
static size_t  xx_in_counter = 0U, xx_out_counter = 0U;
/******************************************************************************/
void xx_putchar (uint8_t value)
{
  xx_buf[xx_in_counter++] = value;
  xx_in_counter &= XX_BUF_SIZE_MASK;
}
/******************************************************************************/
int xx_getchar (void)
{
  int retval = -1;
  if (xx_out_counter != xx_in_counter)  {
    retval = (int)xx_buf[xx_out_counter++];
    xx_out_counter &= XX_BUF_SIZE_MASK;
  }
  return retval;
}
/******************************************************************************/
/* если еcть функция getchar */
void process_xx_buf (void)
{
  int value;
  while ((value = xx_getchar()) >= 0)  {
    ....
  }
}
/******************************************************************************/
/* без использования функции getchar (например, если её вообще нет) */
void process_xx_buf (void)
{
  while (xx_out_counter != xx_in_counter)  {
    uint8_t value = xx_buf[xx_out_counter++];
    xx_out_counter &= XX_BUF_SIZE_MASK;
    ....
  }
}