Полезные Bash Shell команды и однострочные скрипты

Т. к. количество всяких полезный команд и скриптиков для консоли Linux неуклонно растет и всех их не упомнишь, буду записывать сюда что-нибудь эдакое полезное.
Статья будет дополняться.
1. Сделать что-либо со всеми файлами в папке, например, распаковать все zip архивы в текущей папке:
for f in *.zip ; do unzip $f ; done
2. То же самое, только с файлами из поддиректорий текущей. Например, установить rpm пакеты:
for D in *; do [ -d “${D}” ] && yum install ${D}/*.rpm ; done
3. Добавить пользователя в группу:
usermod -a -G group user
4. Как расшарить содержимое папки по протоколу HTTP.
Заходим в нужную папку и выполняем команду:
python -m SimpleHTTPServer 8080
Далее зайдя в браузере по адресу http://ip_of_that_server:8080, мы увидим содержимое с возможностью навигации и скачивания файлов:

5. Получение информации о Virtual Hosts для apache2 в Debian Linux:
apache2ctl -t -D DUMP_VHOSTS
6. Создание файла заданного размера:
truncate -s 14M filename

7. Замена строчек в текстовом файле:
sed -Ei ‘s/foo|bar|baz/foobar/g’ file
Заменить foo, bar или baz на foobar
8. Подмонтировать CD-ROM с указанием типа файловой системы:
mount -t iso9660 /dev/scd0 /media/cdrom
9. Посмотреть параметры загрузки ядра Linux:
cat /proc/cmdline
10. Максимальный уровень компрессии в tar:
env GZIP=-9 tar cvzf file.tar.gz /path/to/directory

Проверка доступности портов между двумя Linux-машинами (для Solaris тоже работает)

Бывают ситуации, когда нам необходимо проверить видимость TCP портов одной машины для другой. Казалось бы всё просто – telnet. А если на серверной машине еще не установлено или не запущено приложение, слушающее нужный порт? Я уверен, что существует масса способов, но мне было проще написать 2 маленьких скрипта на Python.

Один скрипт – сервер. Слушает заданный порт и пишет в консоль информацию о клиентах. А второй – клиентский скрипт – стучится по заданному IP в заданный порт и возвращает ответ от сервера (если порт доступен).

Серверный скрипт.

#!/usr/bin/env python
import socket, sys
# Server address and buffer size
TCP_IP = '0.0.0.0'
BUFFER_SIZE = 1024
# Usage string
usage = "server.py PORT"
# Check number of arguments and print usage if not enough arguments
if (len(sys.argv) < 2):
print(usage)
sys.exit(0)
TCP_PORT = int(sys.argv[1])
# Create socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
# Listen for client connection until Ctrl+C will be pressed
while 1:
c = s.accept()
cli_sock, cli_addr = c
cli_sock.send("Hello, person from %s"%(str(cli_addr)))
cli_sock.close()
print("received data from:", str(cli_addr))


Запуск. Копируем в текстовый файл вышенаписанный код и запускаем:

python server.py <port>

Клиентский скрипт.

#!/usr/bin/env python
import socket, sys
usage = "client.py IP PORT"
# Check number of arguments and print usage if not enough arguments
if (len(sys.argv) < 3):
print(usage)
sys.exit(0)
TCP_IP = sys.argv[1]
TCP_PORT = int(sys.argv[2])
BUFFER_SIZE = 1024
# Create socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
# Recieving response from the server
data = s.recv(BUFFER_SIZE)
s.close()
print("received data:", data)

Запуск. Копируем в текстовый ф
айл вышенаписанный код и запускаем:

python client.py <server_IP> <server_port>

http://geckich.blogspot.com/

Python, извлечение параметров из Post или Get запросов.

Извлекать параметры, введенные в форму (get или post), довольно легко. В этом поможет следующая конструкция:

from mod_python import util

def handler(req):
   form_data = util.FieldStorage(req, keep_blank_values=1)
   myparameter = form_data.getfirst("parameter")

В myparameter теперь находится значение того, что было передано с именем “parameter”. Например, того, что было в ведено в “EditBox1”.

SQLAlchemy в Python

В python для работы с MySQL есть библиотечка SQLAlchemy.

У неё много всяких фишек-плюшек, но я в подавляющем большинстве случаев использую конструкции такого типа:

from sqlalchemy import create_engine
b_connection_string = 'mysql://user:password@localhost/db_name'
user = "admin"
db = create_engine(db_connection_string)
for row in db.execute("select Permissions from users where Name = "%s""%(user)):
result.append(str(row))
Где в 1й строчке мы импортируем функцию, затем создаем соединение с БД, а затем выполняем какой-то запрос. В итоге мы получим такую конструкцию (в данном примере):

[“(‘On, Off, Bla-bla’,)”]

Теперь можно облагородить результат, добавив , например:

result = result[0].replace("('","")
result = result.replace("',)","")
result = result.replace(", ", ",")

Получим в result:  ‘On, Off, Bla-bla’

http://geckich.blogspot.com/

Hello world! с помощью mod_python

Написание сайта с использованием mod_python состоит из двух этапов: конфигурирование сервера (apache) и собственно написание кода.

1. Конфигурация сервера:
Вначале установим модуль, если его еще нет:

aptitude install libapache2-mod-python
a2enmod python

Подредактируем, например, на Debian файл /etc/apache2/sites-available/default :

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www
        <Directory /var/www/>
                Options Indexes MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
                AddHandler mod_python .py        #говорит апачу передавать обработку файлов *.py в mod_python
                PythonHandler index                     #говорит, в каком файле находится обработчик хэндлеров.
                DirectoryIndex index.py                #указывает, какой файл отображается по-умолчанию в директории
        </Directory>
        ErrorLog ${APACHE_LOG_DIR}/error.log
        LogLevel warn
        AddHandler mod_python .py
        PythonHandler mod_python.publisher
        PythonDebug On                                  #включает выведение ошибок в браузер - удобно пр иотладке
        DirectoryIndex index.py
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Активируем виртуалхост (если он не активен) и перезапускаем веб-сервер, чтобы изменения вступили в силу:

a2ensite default
service apache2 restart

2. Написание кода:
from mod_python import apache          #импорт класса apache
def handler(req):                      #функция обработки хэндлера
    req.content_type = "text/html"     #задаем тип содержимого веб-страницы
    req.send_http_header()             #посылка дефолтового хэдера html-страницы
    req.write("Hello World!")          #отправляем Hello World! на страницу
    return apache.OK                   #рендеринг страницы с кодом ОК

Называем файл index.py и сохраняем в директорию виртуал-хоста (в нашем примере это /var/www), не забывая сменить хозяина файла на www-data. Перед проверкой нужно удалить дефолтовый файл index.html из директории виртуалхоста и удалить русскоязычные буквы из питоновского файла – иначе будет ругаться.

Вот так выглядит Hello World на mod_python:

Кодинг на Python в NetBeans (7.2.1)

Я перепробовал много IDE для написания кода на питончике – начиная с обычного nano и заканчивая платными продуктами – PyCharm и WingIDE. Но в итоге выбор пал на бесплатный NetBeans, т. к. выкладывать 100 баксов за платную ИДЕ как-то не хочется… Итак, приступим (описанное здесь я тестировал на ОС Debian 7 и Oracle Linux 6.3).

1. Качаем Java SE SDK с официального сайта Oracle и устанавливаем

2. Качаем с оф. сайта последнюю стабильную версию (на момент написания статьи это была версия 7.2.1) – http://netbeans.org/downloads/ и качаем любую версию, устанавливаем. При установке может попросить указать папку с Java SDK – указываем (если мы качали .tar.gz).

3. А теперь сама “Магия” 🙂 Запускаем наш свеженький NetBeans и переходим в меню Tools > Plugins, вкладка Settings и нажимаем Add, указываем какое-то вменяемое имя и как URL – http://deadlock.netbeans.org/hudson/job/nbms-and-javadoc/lastStableBuild/artifact/nbbuild/nbms/updates.xml.gz

4. Переходим на вкладку Available Plugins и в поиску набираем python. Будет 3 плугина – устанавливаем, презапускаем IDE, ждем пока она проиндексирует питоновские модули, и кодим на питоне с автодополнением и т. п. 🙂

http://geckich.blogspot.com/

Django ошибка django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module: No module named MySQLdb при синхронизации БД.

Вы настроили параметры соединения с БД MySQL в settings.py, но при выполнении синхронизауии

python ./manage.py syncd

Вылетает простыня ошибок, а в конце:

django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module: No module named MySQLdb

Проблема в отсутствии моделя mysql для питона.
Решение:

apt-get install python-mysqldb

Для других конфигураций работают команды:

pip install MySQL-python
easy_install MySQL-python

http://geckich.blogspot.com/

Удаление и архивирование файлов в Windows 2003 с помощью PowerShell

Модифицировал предыдущий скрипт.

Теперь он считывает из текстового файла маски файлов, которые надо заархивировать и удалить, затем делает своё черное дело 🙂

Единственный косяк, который пока не понял как устранить – архив уже должен существовать и быть архивом… Т. е. защиты от дурака не получилось у меня. Функция New-Item или как-то так создает файл, но текстовый – и это не подходит.

Вначале идет часть объявления, где в переменные заносятся все пути (чтобы легче было менять “под себя”), затем идет архивирование (если оно вообще нужно), а затем удаление.

####### define parameters
#----- get current date ----#
$Now = Get-Date
#----- define amount of days ----#
$Days = "10"
#----- define folder where files are located ----#
$TargetFolder = "C:gbQuoteServer"
#----- define LastWriteTime parameter based on $Days ---#
$LastWrite = $Now.AddDays(-$Days)
#----- define delete list file path
$Del_List = "c:scriptsfiles.txt"
#----- define files fore archiving list file path ---#
$Arch_List = "c:scriptsarchive.txt"
#----- define archive file path - this file MUST exist! ---#
$Arch_Path = "c:scriptstest.zip"
####### archiving part
foreach ($_ in Get-Content $Arch_List)
{
$Files = Get-Childitem $TargetFolder -Include $_ -Recurse | Where {$_.LastWriteTime -le "$LastWrite"}
foreach ($File in $Files)
{
if ($File -ne $NULL)
{
write-host "Archiving File $File" -ForegroundColor "Green"
$ZipFile = (new-object -com shell.application).NameSpace($Arch_Path)
$ZipFile.CopyHere($_.fullname)
}
else
{
Write-Host "No more files to archive!" -foregroundcolor "Green"
}
}
}

####### deleting part
foreach ($_ in Get-Content $Del_List)
{
$Files = Get-Childitem $TargetFolder -Include $_ -Recurse | Where {$_.LastWriteTime -le "$LastWrite"}
foreach ($File in $Files)
{
if ($File -ne $NULL)
{
write-host "Deleting File $File" -ForegroundColor "DarkRed"
Remove-Item $File.FullName | out-null
}
else
{
Write-Host "No more files to delete!" -foregroundcolor "Green"
}
}
}
Содержимое файлов со списками примерно такого формата:

B*.txt
*.dll
Del*f.doc

и т. п.

http://geckich.blogspot.com/

Как удалить файлы старше 10 (например) дней в Windows 2003

После некоторого гугления я понял, что это проще всего сделать на PowerShell.

Если он еще не установлен в системе, то берем тут -> Windows PowerShell 1.0 English-Language Installation Package for Windows Server 2003 . Возможно, выругается что нету .NET Framework Version 2.0 Redistributable Package. Тогда берем его там же, у Мракобесов: Microsoft .NET Framework Version 2.0 Redistributable Package (x64) или Microsoft .NET Framework Version 2.0 Redistributable Package (x86) . Также нужен как минимум Service Pack 1.

Инсталляция идет типа Далее, Далее, Финиш 🙂
Затем запускаем наш павер шелл и видим синенький экранчик с очень хорошим юзабилити (растягиваемый, работа с буфером мышкой – н ето что убогая стандартная CMD).

Сразу проверяем, разрешено ли у нас запускать скрипты:

Get-ExecutionPolicy

Скорее всего нет – т. е. вернет что-то типа Restricted. Посему юзаем команду, меняющую “политику партии”:

Set-ExecutionPolicy RemoteSigned

Теперь создаем где-нибудь текстовый файл с расширением .ps1 и пишем в него:

#----- получаем текущую дату и пихаем в переменную ----#
$Now = Get-Date
#----- задаем количество дней старше которых файлы будут удаляться ----#
$Days = "10"
#----- задаем папку которая будет чиститься ----#
$TargetFolder = "C:ApplicationsLogs"
#----- вот тут самое прикольное - задаем маску, то ли это просто расширение ----#
#----- то ли это будут файлы какогото спец формата, например такие PROG_Date.log где Date - дата ----#
$Extension = "PROG*.log"
#----- здесь делаем дату за которой будут удаляться файлы ---#
$LastWrite = $Now.AddDays(-$Days)
#----- получаем список файлов. Если не надо рекурсии то убираем соотв. параметр ---#
#----- если надо удалить тупо все файлы старше 10 дней то убираем -Include $Extension ---#
$Files = Get-Childitem $TargetFolder -Include $Extension -Recurse | Where{$_.LastWriteTime -le "$LastWrite"}
#----- в цикле вербозно удаляем все полученные файлы ---#
foreach ($File in $Files)
{
if ($File -ne $NULL)
{
write-host "Deleting File $File" -ForegroundColor "DarkRed"
Remo ve-Item $File.FullName | out-null
}
else
{
Write-Host "No more files to delete!" -foregroundcolor "Green"
}
}

Напоследок, если хотим сделать shedule, то пишем батник с содержимым типа такого:
%SystemRoot%system32windowspowershellv1.0powershell.exe -command “c:scriptsdelete.ps1”
Где вначале идет путь к павер шеллу (у вас он может отличаться), а в конце – путь к файлу со скриптом.
Затем пихаем батник в планировщик.
Усё, товарищи. 
http://geckich.blogspot.com/