Bash Ждать пока не завершится процесс

Бывает, что в bash скрипте необходимо подождать пока не завершиться какой-то процесс. Если вы знаете его pid, то это можно реализовать так:

while ps -p `cat $PID_FILE` > /dev/null; do sleep 1; done

Ошибка 504 Gateway Timeout (time out) nginx+apache

Если возникла ошибка  504 Gateway Timeout (time out) в связке nginx+apache то увеличим на сервере допустимое время выполнения скриптов и ожидания ответа:
php.ini:
1
max_execution_time = 900
nginx.conf:
1
2
3
4
proxy_read_timeout  900;
client_header_timeout  10m;
client_body_timeout    10m;
send_timeout           10m;
Теперь есть 900 секунд (15 минут) на выполнение скриптов.

Bash скрипт универсальный распаковщик

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

#!/bin/bash
#
#

Z="compress -d"
gz="gunzip"
bz="bunzip2"
zip="unzip -qo"
rar="unrar x -id -y"
tar="tar xf"
7z="p7zip -d"

if [ $# -eq 0 ]; then
    echo "Usage: decompress file or files">&2
    exit 1
fi

for name
do
	if [ ! -f "$name" ] ; then
		echo "$0: file $name not found." >&2
		continue
	fi

	if [ "$(echo $name | egrep '(\.Z$|\.gz$|\.bz2$|\.zip$|\.rar$|\.tar$|\.tgz$|\.7z$)')" = "" ] ; then
		echo "Skipped file ${name}: it's already decompressed." 
      		continue
	fi

	extension=${name##*.}

	case "$extension" in
		Z ) echo "Filetype is Z. Decompressing..."
		    $Z "$name"
		    ;;
		gz ) echo "Filetype is gz. Decompressing..."
		     $gz "$name"
		     ;;
		bz2 ) echo "Filetype is bz2. Decompressing..."
 		     $bz "$name"
		     ;;
		zip ) echo "Filetype is zip. Decompressing..."
		      $zip "$name"
		      ;;
		rar ) echo "Filetype is rar. Decompressing..."
		      $rar "$name"
		      ;;
		tar ) echo "Filetype is tar. Decompressing..."
              	      $tar "$name"
              	      ;;
		tgz ) echo "Filetype is tgz. Decompressing..."
              	      $tar "$name"
                     ;;
               7z ) echo "Filetype is 7z. Decompressing..."
                     $7z "$name"
	esac

done

exit 0


Простой скрипт для бэкапа MySQL баз


#!/bin/bash

# Variables
CNF=/etc/mysql/debian.cnf
BACKUPDIR=/var/backups/mysql/
DATE=`date +%F`
OLDDAYS=7

# Main part
for DATABASE in `echo SHOW DATABASES | mysql —defaults-file=${CNF} —skip-column-names`;do
BACKUPNAME=${BACKUPDIR}${DATABASE}.sql.${DATE}
BZBACKUPNAME=${BACKUPNAME}.bz2
echo Dumping ${DATABASE} into ${BZBACKUPNAME}
mysqldump —defaults-file=${CNF} ${DATABASE} > ${BACKUPNAME}; bzip2 -f ${BACKUPNAME}
done

# Deleting old backups

find ${BACKUPDIR} -mtime +${OLDDAYS} -delete

Дампит и сжимает базы данных.
Можно (и нужно) добавить его в крон, например:

00 05 * * * root /usr/local/sbin/mysqlbackup.sh

JS Скрипт определяющий высоту iframe

Вот, столкнулся с такой проблемой, нужен был js скрипт для корректного определения высоты <iframe>. Поискав в гугле и испробовав с десяток различных вариантов,но к сожалению, я так и не смог добиться желаемого результата. В итоге, абсолютно случайно изучая проект www.eqdkp.com наткнулся на скрипт решивший все мои проблемы. И так, непосредственно перед <iframe> располагаете данный скрипт:

<script type="text/javascript">

var iframeids=["boardframe"]
var iframehide="no"
var getFFVersion=navigator.userAgent.substring(navigator.userAgent.indexOf("Firefox")).split("/")[1]
var FFextraHeight=parseFloat(getFFVersion)>=0.1? 3 : 0 //extra height in px to add to iframe in FireFox 1.0+ browsers

function resizeCaller() {
var dyniframe=new Array()
for (i=0; i<iframeids.length; i++){
if (document.getElementById)
resizeIframe(iframeids)
//reveal iframe for lower end browsers? (see var above):
if ((document.all || document.getElementById) && iframehide=="no"){
var tempobj=document.all? document.all[iframeids] : document.getElementById(iframeids)
tempobj.style.display="block"
}
}
}

function resizeIframe(frameid){
var currentfr=document.getElementById(frameid)
if (currentfr){
currentfr.style.display="block"
if (currentfr.contentDocument && currentfr.contentDocument.body.offsetHeight) //ns6 syntax
currentfr.height = currentfr.contentDocument.body.offsetHeight+FFextraHeight;
else if (currentfr.Document && currentfr.Document.body.scrollHeight) //ie5+ syntax
currentfr.height = currentfr.Document.body.scrollHeight;
else if (currentfr.contentWindow && currentfr.contentWindow.body.document.scrollHeight) //Opera?
currentfr.style.height = currentfr.contentWindow.document.body.scrollHeight;
if (currentfr.addEventListener)
currentfr.addEventListener("load", readjustIframe, false)
else if (currentfr.attachEvent){
currentfr.detachEvent("onload", readjustIframe) // Bug fix line
currentfr.attachEvent("onload", readjustIframe)
}
}
}

function readjustIframe(loadevt) {
var crossevt=(window.event)? event : loadevt
var iframeroot=(crossevt.currentTarget)? crossevt.currentTarget : crossevt.srcElement
if (iframeroot)
resizeIframe(iframeroot.id);
}

function loadintoIframe(iframeid, url){
if (document.getElementById)
document.getElementById(iframeid).src=url
}

if (window.addEventListener)
window.addEventListener("load", resizeCaller, false)
else if (window.attachEvent)
window.attachEvent("onload", resizeCaller)
else
window.onload=resizeCaller

</script>

А затем идет сам <ifram>, обязательно с id=»boardframe», как пример:

<iframe onload="window.scrollTo(0,0)" src="http://teaseo.ru id="boardframe" allowtransparency="true" 
height="" width="99%" scrolling="no" marginwidth="0" marginheight="0" frameborder="0" vspace="0" hspace="0"></iframe>

Linux очистка кэша из памяти

Линукс достаточно грамотно распределяет память, используя свободное пространство под кэш и в случаи необходимости по требованию ядра освобождает необходимое количество. Для того что бы просмотреть состояние памяти в данный момент выполните команду:

free

результат будет приблизительно такой:

             total       used       free     shared    buffers     cached
Mem:       8165704    7415508     750196          0     865540    4513180
-/+ buffers/cache:    2036788    6128916
Swap:     10223608        196   10223412

В моем случаи кэш занимает 4.5 Гб. Если вы по каким-то причинам хотите очистить кеш, выполните:

sync; echo 3 > /proc/sys/vm/drop_caches

Bash Убираем коментарии в файле

Я думаю каждый администратор сталкивался с такой проблемой, когда нужно убрать все закоментированые строки в конфигурационном файле или скрипте. Для этого вы можете воспользоваться вот таким скриптом:

#!/bin/bash
#
#
sed '1p; /^[[:blank:]]*#/d; s/[[:blank:]][[:blank:]]*#.*//' $1 > new

Правда есть небольшая проблема, возникнет куча пустых строк, поэтому мы немного переделаем скрипт:

#!/bin/bash
#
#
sed '1p; /^[[:blank:]]*#/d; s/[[:blank:]][[:blank:]]*#.*//' $1 | sed -e 's/[\t ]//g;/^$/d' > new

 

Установка CentALT репозитария

CentALT это небольшой репозитарий, автор которого сосредоточил свое внимание всего на несколько пакетов, за-то обновления этих пакетов появляются в кратчайшие сроки. Вот список пакетов:

Clamav
Clamsmtpd
Conntrack-tools
Dnstop
Dovecot
Postfix
Httpd
Mc
Memcached
Mod_rpaf
Mod_realip2
Mysql
Nagios
Nagios-plugins
Nginx
Php
Spawn-fcgi
Unbound
Vsftpd
flow-tools
fprobe
ipt_netflow
softflowd
ipcad
quagga
А также модули ядра connlimit, ipmark, ipset, ipp2p.

Установка репозитария для i386:

rpm -ihv http://centos.alt.ru/repository/centos/5/i386/centalt-release-5-3.noarch.rpm

для x86_64:

rpm -ihv http://centos.alt.ru/repository/centos/5/x86_64/centalt-release-5-3.noarch.rpm

Codeigniter аутентификация через Ldap

Так, как последнее время я работаю используя Codeigniter, то соответственно начал искать модуль для LDAP аутентификации, в итоге, поиски привели меня на Хабр. Статья оказалась полезной, и помогла начать работу с библиотекой adldap.php

В процессе создания внутреннего сайта одной из российских компаний, возникла необходимость ограничить доступ пользователей к некоторым страницам, функциям. Так как все пользователи в домене, то и на сайте есть смысл использовать доменную аутентификацию.

Найти самостоятельно информацию в принципе не трудно. Поисковые системы еще ни кто не отменял. Я просто решил собрать найденные кусочки и объединить их в один, на русском языке.

Допустим, что CI уже установлен и настроен. Добавим библиотеку и конфигурационный файл.Конечно, существуют некоторые функции в самом PHP, но использовать их не всегда рационально. За основу возьмем библиотеку adLDAP. В ней есть все необходимое и даже больше.

Первым делом создадим конфигурационный файл, например adldap.php и положим его в \system\application\config\

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

$config['account_suffix'] = '@dom.ru';
$config['base_dn'] = 'DC=dom,DC=ru';
$config['domain_controllers'] = array ("DC01.dom.ru");
$config['ad_username'] = 'web_user';
$config['ad_password'] = 'web_passS8';
$config['real_primarygroup'] = true;
$config['use_ssl'] = false;
$config['use_tls'] = false;
$config['recursive_groups'] = true;
?>

Далее необходимо добавить библиотеку. Но как сделать так, что бы ей можно было пользоваться в CI, как остальными? За нас это уже сделал один программист, и предоставил для общественного пользования (онутверждает, что лицензия не нарушена). Ее мы и добавим в \system\libraries\ и назовем, например Adldap.php.

После выше описанных манипуляций библиотекой можно пользоваться в Codeigniter-е, как и другими, например:

<?php
$this->load->library('Adldap');
$this->adldap->authenticate($username, $password);
?>

Напишем небольшой код авторизации

Сделать это проще простого.
Во-первых, создадим форму для ввода логина и пароля:

<?php
<form_ action=«info.dom.ru/login/gateway» method=«post»>
<input_ name=«username» type=«text» value=«Логин»>
<input_ name=«password» type=«password» value=«Пароль»>
<input_ type=«submit» name=«submit» value=«Войти» />
</form_>
?>

Во-вторых, контролер и саму функцию для авторизации в домене. Но домен большой и пользователей много и если просто проверять пароль и логин, то к ограниченным частям сайта будут иметь все члены домена.

Для более тонкой настройки нужен еще один параметр для проверки — группа (Active Directory). Назовем ее, например Web_Group, и добавим нужных нам пользователей:

<?php
//Создаем контроллер
class login extends Controller {

//Функция для проверки логина, пароля и группы
function gateway() {

//Подключаем библиотеку
$this->load->library('Adldap');

//Проверяем логин и пароль
$authUser = $this->adldap->authenticate($this->input->post('username'), $this->input->post('password'));

//проверяем наличие пользователя в группе
$groupinfo = $this->adldap->user_ingroup($this->input->post('username'), 'Web_Group', 'NULL');

//В случае если $authUser и $groupinfo истина
if ($authUser === true and $groupinfo === true) {

//Осталось только добавить информацию в массив сессии о том, что проверка успешна и доступ к определенным ресурсам открыт
$data = array('username' => $this->input->post('username'), 'usergroup_access' => 'Web_Group', 'is_logged_in' => true);
$this->session->set_userdata($data);
redirect();
} else {
echo "Ошибка авторизации";
}
}
}
?>

Вот и все. Теперь в любой другой функции можно делать проверку и в зависимости от результата предоставлять или не предоставлять доступ.
Примерно это должно выглядеть так:

<?php
function view_data() {

//Вытаскиваем и проверяем прошел или нет пользователь авторизацию
if ($this->session->userdata('is_logged_in') == true) {

echo "Доступ к данным открыт";

} else {

echo "Доступ закрыт";
}
}
?>

Теперь осталось только дописать функцию уничтожения сессии (Logout):

<?php
function logout() {
$this->session->sess_destroy();
redirect();
}
?>