ITСooky

IT-рецепты съедобные и не очень!

Запускаем Linux через Windows Subsystem for Linux с примерами!

дата 05.09.2019

Есть такая возможность, через встроенные функции Windows 10 запустить почти настоящий Linux! Зачем? Для автоматизации через консольные комманды. Windows называют Виндовсом(и другими словами) не просто так, а за окна за то что все приходится делать руками и глазами, хотя изначально в истории компьютеров все шло по пути автоматизированной работой с информацией в консоле командами и регулярными выражениями. Объемы информации растут, грамотность пользователей тоже, сложность и практичность задач тоже и Майкросфот поэтому накатил Linux на Windows, потому что свой скриптовый язык PowerShell не взлетел, он не кросплатформенный, он закрытый, его массово не используют, поэтому нет работающих примеров на любой случай! А в Linux это все есть, потому что уже десятилетиями используется и развивается!

Windows 10 буду ставить на виртуальную машину, вот этот www.microsoft.com/en-us/evalcenter/evaluate-windows-10-enterprise он работает 90 дней за просто так! Что удивительно свеже скаченный образ, залипает на часок на обновление чего-то

Ну раз вы это читаете у вас Windows и вы к этому привыкли, меня это просто сильно удивляет каждый раз когда запускаю Windows!

Когда загрузится ищем «Turn Windows Features», раньше еще надо было включать режим разработчика, но теперь не надо

Поставим галочку в Windows Subsystem for Linux

Через магазин Майкрософт установим Ubuntu 18.04 LTS

После установки запускаем Ubuntu 18.04 LTS через меню программ ииии он чего-то опять до устанавливает — от Виндовс заразился!

Ок, запустилось!

Виндовс диск примонтирован в Linux, на него можно заходить
cd /mnt/c
ls -l

тут можно создать папку
mkdir ubuntu
из виндовс она будет выглядеть как обычная папка, можно туда писать

Начало
Хочу на Windows машину закинуть папку с Linux машины. Как? Скопировать на флешку и донести — нет это же компьютер, все можно сделать по компьютерному без ног!

На Linux машине у меня установлен
sudo apt install openssh-server

На Windows Ubuntu захожу в папку в которую хочу скачать
cd /mnt/c/ubuntu
И качаю с линукс машины нужную папку
scp -r alexandr@192.168.1.13:/home/alexandr/Documents/nespi ./
ввожу пароль от линукс машины и все скачалось!
Так же можно положить на линукс машину из виндовс
scp ./somefile.txt alexandr@192.168.1.13:/home/alexandr/Documents/nespi

Теперь например мне надо узнать размер файла в названи которого есть 001.jpg в этой папке
я могу сделать
ls -l
и посмотреть глазами

но зачем глаза, если я могу скомандовать так чтобы мне сразу дали цифру размера этого файла
вот так
ls -l | grep 001.jpg | awk '{print $5}'

И в этом вся прелесть, можно формулировать конкретные запросы к компу и получать конкретные ответы, и все это в виде команд, а не пойди туда нажми мышкой и поэтому это можно автоматизировать!

Строка простая. Первая команда ls -l заканчивается знаком | это значит все что она выдала идет в следующею команду. grep берет из этого только строку где есть 001.jpg и кидает в следующею комманду. awk из этой строки берет 5 столбец, где как раз размер файла.

Не хотите видеть на экране цифру, давайте запишем в файл размеры всех jpg фалов, да чтобы имя шло первым
ls -l | grep .jpg | awk '{print $9" "$5" bytes"}' > list.txt

вот что получаем в файле list.txt

raspberrypi_nespi_itcooky001.jpg 485839 bytes
raspberrypi_nespi_itcooky002.jpg 238575 bytes
raspberrypi_nespi_itcooky003.jpg 233167 bytes
raspberrypi_nespi_itcooky004.jpg 35420 bytes
raspberrypi_nespi_itcooky005.jpg 137017 bytes
raspberrypi_nespi_itcooky006.jpg 133464 bytes
raspberrypi_nespi_itcooky007.jpg 83661 bytes

Если например хотим чтобы вместо байт были килобайты, можно в ls добавить этот параметр
ls -l --block-size=K| grep .jpg | awk '{print $9" "$5}' > list.txt

А можно заморочиться и сделать через awk добавить мат операцию и отбросить от числа десятки, не округляя
ls -l | grep .jpg | awk '{printf ("%s %d %s\n", $9, $5/1000, "Kbytes")}' > list.txt

raspberrypi_nespi_itcooky001.jpg 485 Kbytes
raspberrypi_nespi_itcooky002.jpg 238 Kbytes
raspberrypi_nespi_itcooky003.jpg 233 Kbytes
raspberrypi_nespi_itcooky004.jpg 35 Kbytes
raspberrypi_nespi_itcooky005.jpg 137 Kbytes
raspberrypi_nespi_itcooky006.jpg 133 Kbytes
raspberrypi_nespi_itcooky007.jpg 83 Kbytes

Тут в awk не print a printf а это же Сишный оператор! Сначала описывается где что будет стоять в «», а потом откуда брать по очереди эти три значения. %s это вставить строку, %d это взять от числа только целое, если написать %.0f то он тоже оставит отчисла только целое но округлит то что после запятой. \n это переход на следующею строку!

Обрабатываем пачками фотографии в консоли Linux для Windows
Есть папка с кучей фоток и я хочу чтобы они были все на одной страничке HTML чтобы кликнул и сразу все посмотрел в браузере. Просто, полезно, но как сделать? В консоле легко!

Сначала смотрю есть ли коммандная оболочка bash коммандой
bash —version

Показывает версию, значит есть!
Будем писать файл значит нужен какой-то редактор… хардкорный вариант vi, человечсекий MC это и браузер файлов и редактор.

Устанавливаем MC
sudo apt update
sudo apt install mc

Запускаем
mc
Выбираем файл, внизу меню что с ним делать, выйти F10

Создаем файл fotogen.sh с текстом

#!/bin/bash
echo "<html><body>" > foto.html
ls -l *.jpg | awk '{print "<img src="$9" width=100%>"}' >> foto.html
echo "</body></html>" >> foto.html

Запускаем
sh ./ftogen.sh
И получаем страницу с фотками всегда ужатыми или растянутыми на размер страницы. Если растягивать не надо надо убрать width=100% Вот так быстро и просто, не надо копировать по сто раз одну строку и менять одну цифорку, как я делать еще всего…ну в детстве

А теперь хочу сделать чтобы показывались превьюшки, а большие картинки открывались по клику. Можно сделать маленькие картинки, автоматом в програррме IrfanView хорошая виндосовая программа, но можно и в консоли сделать!

Ставим imagemagick
sudo apt-get install imagemagick

Вот вот эта штука, она какая-то оригинальная однако! Пришлось долго понимать как с ней работать, благо в интернетах куча примеров! Проге 29 лет и могла бы к этому возрасту уже стать как все, работать с ней использую обычную консольную логику невозможно, но она сама в себе решает эту пробелему. Есть основная комманда для работы с картинками convert — но она не умеет писать новый файл в новую папку. Есть другая команда mogrify и она точно такая же как convert только умеет писать в новую папку, но она она вывернутая и pipe чтоли не понимает.

mogrify -path mini -resize 300 -quality 80 *.jpg

кладет в папку mini, которая в том месте где мы находимся (обычно это обознасется ./ но тут вот), все jpg меняя размер и качество

Вот готовый код для генерации страницы фоток с превьюшками
Создаем файл fotogen2.sh с текстом

#!/bin/bash
mkdir web ./web/mini
cp ./*.jpg ./web
mogrify -path web/mini -resize 300 -quality 80 ./web/*.jpg
echo "<html><body>" > ./web/foto.html
ls -l *.jpg | awk '{print "<a href=./"$9"><img src=./mini/"$9"></a>"}' >> ./web/foto.html
echo "</body></html>" >> ./web/foto.html

Скрипт у нас лежит в папки где есть фотки которые мы хотим обработать, они все с расширением .jpg
запускаем
sh ./fоtogen2.sh
Сначала делаем две папки. Копируем в первую оригиналы. Берем из первой оригиналы и кладем мини во вторую. В первую генерируем страницу. Получается в папке web все есть и картинки и превьюшки для просмотра надо открыть foto.html папку web можно уносить с собой или выкладывать на вебсервер или файлшару

Следим за состоянием картриджа в принтере или принтерах
Типовая задача, допустим у вас стописят принтеров, и вы хотите чтобы информация об картриджах висела на стене на мониторе, и как то наглядно представлялась!

У меня один принтер и не самый удачный, точнее самый неудачный (OKI я не считаю). Kyocera FS 1125 MFP купил потому что поверил что он сетевой, так и было написано — сканировать по сети не умеет, вебинтерфейса нет. Поверил что он совместим с Linux — умеет только печатать по сети если в названии файла нет русских букв. Kyocera крупный корпоротивный игрок, думаю это его и испортило — присосался к какой-то корпорации на вечно и никак не хочет делать свои продукты конкрентными — не покупайте!

На WSL надо установить snmp
sudo apt install snmp

Надо проверить что на принтере включен snmp. Для этого надо зайти на принтер по USB специальной программой. Скачать её на сайте Kyocera отдельно нельзя, но там есть ISO CD может там она есть…

хотя ладно жахну сразу комнаду может он включен на принтере
snmpwalk -v 2c -c public 192.168.1.2

Действительно, работает! Получаю кучу параметров которые принтер выдает по snmp! Значения их даже у нормальных производителей трудно найти. Но можно вычислить я знаю что сейчас на принтере 11%, что картридж стартовый на 1000 страниц! Но обычно…

snmpwalk -v 2c -c public 192.168.1.2 1.3.6.1.2.1.43.11.1.1.9.1.1
Вот это показывает сколько осталось тсраниц до конца 110 похоже на 11%

snmpwalk -v 2c -c public 192.168.1.2 1.3.6.1.2.1.43.11.1.1.8.1.1
ресурс картриджа 1000

snmpwalk -v 2c -c public 192.168.1.2 1.3.6.1.2.1.43.11.1.1.6.1.1
название картриджа

snmpwalk -v 2c -c public 192.168.1.2 1.3.6.1.2.1.25.3.2.1.1.3.1
название модели принтера

Создаю файл printers.data с описанием принтеров где будет сетевое имя, ip, реальнное имя (тут главное чтобы без пробелов)

NetPrinter1 192.168.1.2 Low_Dep
NetPrinter2 192.168.1.2 Market_Dep
NetPrinter3 192.168.1.100 Food_Dep
NetPrinter4 192.168.1.2 KillersHR_Dep

у меня один принтер так что IP повторяются, и есть один ошибочный IP

Вот код который опрашивает принтеры

#!/bin/bash

#get date
my_date=`date +%Y.%m.%d-%H:%M`

#collect new data from printers
filename="./printers.data"
rm ./snmp.data
 while IFS= read -r line
 	do
           print_ip=`echo ${line} | awk '{print $2}'`    
           print_net=`echo ${line} | awk '{print $1}'`
           print_dep=`echo ${line} | awk '{print $3}'` 
	   print_left=`snmpwalk -r 2 -t 2 -L n -c public -v 2c ${print_ip} 1.3.6.1.2.1.43.11.1.1.9.1.1 | awk '{print $4}'`
	    if [ -z "$print_left" ]
	    then
		    print_left="ERRROR"
	    fi

           print_resurce=`snmpwalk -r 2 -t 2 -L n -c public -v 2c ${print_ip} 1.3.6.1.2.1.43.11.1.1.8.1.1 | awk '{print $4}'`
	    if [ -z "$print_resurce" ]
            then
		    print_resurce="ERRROR"
      	   fi
           print_cartridge=`snmpwalk -r 2 -t 2 -L n -c public -v 2c ${print_ip} 1.3.6.1.2.1.43.11.1.1.6.1.1 | awk '{print $4}'`          
	   if [ -z "$print_cartridge" ]
             then
		     print_cartridge="ERRROR"
	    fi


	   echo "$print_net $print_ip $print_dep $print_left $print_resurce $print_cartridge" >> ./snmp.data


 done < "$filename"

Если принтер не отвечает пишем ERROR. SNMP долго ждет ответа даже опции -r количество попыток -t таймоут не сильно сокрашают ожидание.
Вот такие данные собрались, специально сюда включил даннее из файла принтеров, чтобы потом было легче выводить инфу

NetPrinter1 192.168.1.2 Low_Dep 110 1000 "TK-1120S"
NetPrinter2 192.168.1.2 Market_Dep 110 1000 "TK-1120S"
NetPrinter3 192.168.1.100 Food_Dep ERRROR ERRROR ERRROR
NetPrinter4 192.168.1.2 KillersHR_Dep 110 1000 "TK-1120S"

Теперь добавляю к этому скрипту часть где будет генерится стрaница
вот все

#!/bin/bash

#get date
my_date=`date +%Y.%m.%d-%H:%M`

#collect new data from printers
filename="/mnt/c/ubuntu/print/printers.data"
rm /mnt/c/ubuntu/print/snmp.data
 while IFS= read -r line
 	do
           print_ip=`echo ${line} | awk '{print $2}'`    
           print_net=`echo ${line} | awk '{print $1}'`
           print_dep=`echo ${line} | awk '{print $3}'` 
	   print_left=`snmpwalk -r 2 -t 2 -L n -c public -v 2c ${print_ip} 1.3.6.1.2.1.43.11.1.1.9.1.1 | awk '{print $4}'`
	    if [ -z "$print_left" ]
	    then
		    print_left="ERRROR"
	    fi

           print_resurce=`snmpwalk -r 2 -t 2 -L n -c public -v 2c ${print_ip} 1.3.6.1.2.1.43.11.1.1.8.1.1 | awk '{print $4}'`
	    if [ -z "$print_resurce" ]
            then
		    print_resurce="ERRROR"
      	   fi
           print_cartridge=`snmpwalk -r 2 -t 2 -L n -c public -v 2c ${print_ip} 1.3.6.1.2.1.43.11.1.1.6.1.1 | awk '{print $4}'`          
	   if [ -z "$print_cartridge" ]
             then
		     print_cartridge="ERRROR"
	    fi
	    print_porcent=`echo $((100*${print_left}/${print_resurce}))`
	    

	   echo "$print_net $print_ip $print_dep $print_porcent $print_left $print_resurce $print_cartridge" >> /mnt/c/ubuntu/print/snmp.data


 done < "$filename"

echo "<html>
<meta http-equiv=\"refresh\" content=\"65\">
<body>
<style>
body {
    background-color: #000000;
    }
    a:link, a:visited, .custom { 
        color: #ffffff;
}
h1 {
        color: #FF0000;
	font-size: 14px;
}
p {
    color: #ffffff;
    }
    </style>
    <p>Printers Data: update on $my_date</p>
    <table><tr><td width=120><p>Net name</p></td>
    <td width=120><p>Department</p></td>
    <td width=120><p>Cartridge</p></td>
    <td width=120 align=center><p>%</p></td></tr>" > /mnt/c/ubuntu/print/index.html
  
awk '{print "<tr><td width=120><a href=http://"$2" style=\"text-decoration: none\">"$1"</a></td><td width=120 bgcolor=#1d1e2a><p>"$3"</p></td><td width=120><p>"$7"</p></td><td align=center "} $4 >= 85 && $4 <= 100 { printf "bgcolor=#39901d"} $4 > 50 && $4 < 85 { printf "bgcolor=#37bb0c"} $4 <= 50 && $4 >30 { printf "bgcolor=#ADFF2F"} $4 <= 30 && $4 >15 { printf "bgcolor=#FFFF00"} $4 <= 15 && $4 >= 0 { printf "bgcolor=#ff0000"} {print " width=150>"$4"</td></tr>"}' /mnt/c/ubuntu/print/snmp.data >> /mnt/c/ubuntu/print/index.html    
echo "</table></html>" >> /mnt/c/ubuntu/print/index.html

ВНИМАНИЕ: Тут относительные пути ./ заменил на абсолюбтные /mnt/c/ubuntu/print/ чтобы работал crontab

Первая часть чуть изменена добавлен подсчет процентов оставшегося ресурса print_porcent. HTML страница будет обновлятся каждые 65 секунд, это прописано во второй строчке хтмл. Поля с процентами оставшегося картриджа будут подкрашываться в разные цвета взамисимости от этой велечины. Сетевое имя это ссылка. Итого вот такая картинка получается

Так попробую засунуть это в местный крон
crontab -e
добавяю строку

* * * * * sh /mnt/c/ubuntu/print/printers.sh

Cron в WSL испорченный, его надо стартовать каждый раз руками и от рута чтобы работал
sudo service cron start
sudo service atd start

Можно даже этот скрипт запускать из коммандной строки Виндовс, и пытаться в его же планировщик вставить
C:\Windows\System32\bash.exe -c "/bin/sh/ mnt/c/ubuntu/print/prinetrs.sh"

…но можно же просто посылать предупреждение на почту когда дойдет до низкого уровня картридж!
Для этого ставим
sudo apt-get install ssmtp
Настраиваем редактирую файл? нужны права рут нужно запустить
sudo mc и найти файл в папке /etc/ssmtp/ssmtp.conf
sudo vi /etc/ssmtp/ssmtp.conf
Оставляем только такой текст в файле, со своими данными

root=username@gmail.com
mailhub=smtp.gmail.com:465
rewriteDomain=gmail.com
AuthUser=username@gmail.com
AuthPass=password
FromLineOverride=YES
UseTLS=YES

Теперь идем в свой gmail аккаунт myaccount.google.com/security и в Безопаность включаем Ненадежные приложения, у которых есть доступ к аккаунту

Теперь делаем файл письма mail.txt, да эта штука специфичная однако, с текстом

To: recipient_name@gmail.com
From: username@gmail.com
Subject: Sent from a terminal!

Hi this is only test just ignored. By the way i have bougth butter and cheese, can you next time buy it by yourself, you know i dont have a job and enough mony to buy all food needed!

И шлем, коммандой
ssmtp recipient_name@gmail.com < mail.txt

Все ушло, отлично сработало!!!

Теперь просто скрипт, который будет брать процент картриджа, сравнивать, генерировать письмо и отсылать! Файл назову printmail.sh

#!/bin/bash

#set warning cartridge level
cartridge_war=15
print_ip=192.168.1.2
to_email=recipient_name@gmail.com
from_email=username@gmail.com
#get date
my_date=`date +%Y.%m.%d-%H:%M`

#collect new data from printers
	   print_left=`snmpwalk -r 2 -t 2 -L n -c public -v 2c ${print_ip} 1.3.6.1.2.1.43.11.1.1.9.1.1 | awk '{print $4}'`
	    if [ -z "$print_left" ]
	    then
		    print_left="ERRROR"
	    fi

           print_resurce=`snmpwalk -r 2 -t 2 -L n -c public -v 2c ${print_ip} 1.3.6.1.2.1.43.11.1.1.8.1.1 | awk '{print $4}'`
	    if [ -z "$print_resurce" ]
            then
		    print_resurce="ERRROR"
      	   fi
	    print_porcent=`echo $((100*${print_left}/${print_resurce}))`

	    if [ $print_porcent -lt $cartridge_war ]
	    then
                 echo "To: $to_email\nFrom: $from_email\nSubject: Low toner\nLow carridge! Toner left $print_porcent%, and aprox $print_left pages to print.\nDate:$my_date" > /mnt/c/ubuntu/print/mail2.txt
                 ssmtp $to_email < /mnt/c/ubuntu/print/mail2.txt
	    fi

В консоле запускаю все работает, вставлюка я в Планировшик задач виндовс. Там надо будет запускать

C:\Windows\System32\bash.exe -c "/bin/sh/ mnt/c/ubuntu/print/printmail.sh"

Иду в Task Schedular и меняю в этих окнах вот так


Иии работает! Даже когда никто не залогинен, можно оставлять Windows комп включенным и все будет работать!!!