This is an old revision of the document!
# mkdir -p /srv/ssh/chroot # mkdir -p /etc/ssh/authorized_keys /srv/ssh/chroot # groupadd sftponly # useradd -G www-data -g sftponly -s /usr/sbin/nologin -d /srv/ssh -N USERNAME # find /var/www/static -type d -print0 | xargs -0 chmod g+xwr # find /var/www/static -type f -print0 | xargs -0 chmod g+wr # chmod 775 /var/www/static /srv/ssh/chroot # mount -o bind /var/www/static /srv/ssh/chroot
Subsystem sftp internal-sftp -u 0002 AuthorizedKeysFile /etc/ssh/authorized_keys/%u %h/.ssh/authorized_keys .ssh/authorized_keys Match Group sftponly ChrootDirectory %h ForceCommand internal-sftp -u 0002 AllowTcpForwarding no X11Forwarding no PasswordAuthentication no
LABEL=cloudimg-rootfs / ext4 defaults,discard 0 0 /var/www/static /srv/ssh/chroot none bind 0 0
atrpms-repo-6-7.el6.x86_64 https://www.mirrorservice.org/sites/dl.atrpms.net/el$releasever-$basearch/atrpms/stable
[atrpms] name=Red Hat Enterprise Linux $releasever - $basearch - ATrpms failovermethod=priority #baseurl=http://dl.atrpms.net/el$releasever-$basearch/atrpms/stable baseurl=https://www.mirrorservice.org/sites/dl.atrpms.net/el$releasever-$basearch/atrpms/stable enabled=0 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-atrpms [atrpms-debuginfo] name=Red Hat Enterprise Linux $releasever - $basearch - ATrpms - Debug failovermethod=priority baseurl=https://www.mirrorservice.org/sites/dl.atrpms.net/debug/el$releasever-$basearch/atrpms/stable enabled=0 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-atrpms [atrpms-source] name=Red Hat Enterprise Linux $releasever - $basearch - ATrpms - Source failovermethod=priority baseurl=https://www.mirrorservice.org/sites/dl.atrpms.net/src/el$releasever-$basearch/atrpms/stable enabled=0 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-atrpms
#!/usr/bin/env bash yum --enablerepo=atrpms ffmpeg-devel SRC_DIR=/opt/src/ffmpeg-php [[ -d $SRC_DIR ]] || mkdir -p $SRC_DIR cd $SRC_DIR git clone https://github.com/tony2001/ffmpeg-php.git cd ffmpeg-git grep -ir avcodec_alloc_frame "$SRC_DIR" -l | xargs -I{} sed 's/avcodec_alloc_frame/av_frame_alloc/' -i {} ./configure
#!/usr/bin/env bash _dir=/home/bundle # app root dir _home=/home/passenger # user home dir _addr="0.0.0.0" _port="8191" _pid="$_home/passenger.pid" _log="$_home/passenger.log" _ngxtpl="$_home/nginx.conf.erb" _args="--address $_addr --port $_port --user passenger --environment production --pid-file $_pid --log-file $_log --nginx-config-template $_ngxtpl --daemonize --sticky-sessions --app-type node --startup-file main.js" [[ -f $_home/.nvm/nvm.sh ]] && source $_home/.nvm/nvm.sh export MONGO_URL='mongodb://localhost:27017/mongodb' export ROOT_URL="http://pro-manage.net:$_port" [[ `whoami 2>/dev/null` == passenger ]] || echo "Run as passenger user" cd $_dir case $@ in stop) passenger stop --port $_port --pid-file $_pid ;; start) passenger start $_args ;; restart) $0 stop $0 start ;; status) passenger status --port $_port --pid-file $_pid ;; *) echo "usage: $0 stop | start | restart | status" ;; esac
generate files
for i in $(seq 1 1000000); do echo testing >> $i.txt; done
rm
time rm -f * -bash: /bin/rm: Argument list too long real 0m11.126s user 0m9.673s sys 0m1.278s
find with -exec rm
time find ./ -type f -exec rm {} \; real 14m51.735s user 2m24.330s sys 9m48.743s
find with -delete
time find ./ -type f -delete real 5m11.937s user 0m1.259s sys 0m28.441s
perl
time perl -e 'for(<*>){((stat)[9]<(unlink))}' real 1m0.488s user 0m7.023s sys 0m27.403s
rsync - empty test dir
rsync -a --delete /home/blanktest/ /home/test/ real 2m52.502s user 0m2.772s sys 0m32.649s
clamscan -ri --detect-pua=yes --scan-mail=yes --phishing-sigs=yes --phishing-scan-urls=yes --heuristic-scan-precedence=yes --algorithmic-detection=yes --scan-pe=yes --scan-elf=yes --scan-ole2=yes --scan-pdf=yes --scan-html=yes --scan-archive=yes --detect-broken=yes --block-encrypted=yes /path/to/dir
Задача состояла в разделении точки входа и точки выхода для openvpn.
Entry node | Exit node | |
---|---|---|
OS | Linux CentOS 6.x | FreeBSD 9.x |
Service | openvpn server | none |
External IP | 88.32.99.91 | 162.210.201.13 |
Internal IP | 10.254.10.1 | 10.254.20.1 |
OpenVPN network | 10.254.0.0/16 |
[mysqld] tmpdir=/tmp/mysql [mysqldump] tmpdir=/tmp [client] tmpdir=/tmp
#!/usr/bin/env bash # # Daily backup mysql databases # CLI args: none #exit on error set -e LANG=C PATH="/bin:/usr/sbin:/usr/bin:/sbin:/usr/local/bin:/usr/local/sbin" DATE=$(date +%F) BACKUP_DIR=/home/mysql_backups DUMP_DIR=$BACKUP_DIR/dumps LOG=$BACKUP_DIR/backup.log DAYS=7 DB="all" OPTS="--order-by-primary --add-drop-database" ######################### print_error() { echo "$@"; write_log "[ERROR] $@"; exit 1; } print_info() { echo "$@"; write_log "[INFO] $@"; } write_log() { echo "`date -R -u` $@" >> $LOG; } ########################## # check dir [[ -d $DUMP_DIR ]] || mkdir -p $DUMP_DIR # check permissions on backup dir if PERMS=$(stat --format="%a" $BACKUP_DIR) then # restore chmod [[ $PERMS -eq 700 ]] || chmod 700 $BACKUP_DIR fi # check binaries [[ -f `which mysqldump 2>/dev/null` ]] && MYSQLDUMP=mysqldump || print_error "No mysqldump binary found in $PATH" [[ -f `which mysql 2>/dev/null` ]] && MYSQL=mysql || print_error "No mysql binary found in $PATH" # validate $DB and skip default dbs [[ $DB == all ]] && DB=$(mysql -e 'show databases' | tail -n +2 | grep -v -E "^(information_schema|performance_schema)$") # create dumps for db in $DB do # is db exist? if ! EXISTS=$($MYSQL -s -N -e "show databases" | tail -n +2 | grep -x $db) then print_info "No such database: $db" break fi DUMP_FILE=$DUMP_DIR/$DATE/$db.sql.gz # is dump exist? [[ -s $DUMP_FILE ]] || ( # log print_info "Creating new: $DUMP_FILE" # mkdir mkdir -p $DUMP_DIR/$DATE # add --events to mysql db [[ $db == mysql ]] && OPTS+=" --events" # dump $MYSQLDUMP $OPTS $db | gzip -1 > $DUMP_FILE ) done # remove dirs if OUTDATED_DIRS=$(find $DUMP_DIR -maxdepth 1 -type d -mtime +$DAYS) then for dir in $OUTDATED_DIRS do # log print_info "Deleting outdated: $dir" # rm [[ -d $dir ]] && rm -r "$dir" || print_error "Can't remove $dir" done fi
#!/usr/bin/env bash export LANG=C # must have # 1-column to tabs-separated multicolumn cat 1-col.txt | sort | column # 1-column to spaces-separated multicolumn cat 1-col.txt | sort | column | expand # 1-column to string w/delimiter cat 1-col.txt | sort | paste -sd: # multicolumn to 1-column cat multi-col-spaces.txt | xargs -n 1 | sort # string w/delimiter to 1-column cat 1-string-delim.txt | tr ':' '\n' | sort
#!/usr/bin/env bash # Usage: $0 with no args set -e PATH="/sbin:/bin:/usr/sbin:/usr/bin:/sbin:$PATH" MAIL_TO='[email protected]' SCRIPTS_DIR=/etc/openvpn/easy-rsa ACCOUNTS_DIR=/etc/openvpn/KEYS ##################################### function error_print { echo "ERROR $1" 1>&2 exit 1; } # read account [[ -z $account ]] && echo -n "Provide account name to add: " || error_print "No account provided" read account [[ -z $account ]] && error_print "No account provided" # cd scripts dir [[ -d $SCRIPTS_DIR ]] && cd $SCRIPTS_DIR || error_print "No such dir $SCRIPTS_DIR" # read vars [[ -f vars ]] && source vars || error_print "No such file vars" echo "Creating cert and key for $account" # build key [[ -x pkitool ]] && ./pkitool $account || error_print "No such file pkitool" # make account dir mkdir -p /etc/openvpn/KEYS/$account # copy account cert & key cp $SCRIPTS_DIR/keys/${account}.crt $SCRIPTS_DIR/keys/${account}.key $ACCOUNTS_DIR/$account/ # copy ca cert and tls key cp $SCRIPTS_DIR/keys/ca.crt $SCRIPTS_DIR/keys/ta.key $ACCOUNTS_DIR/$account/ # generate ovpn config cat > $ACCOUNTS_DIR/$account/${account}.ovpn << EOF client remote SERVER'S.EXTERNAL.IP port 1194 proto tcp dev tun nobind persist-key persist-tun ca ca.crt cert ${account}.crt key ${account}.key tls-auth ta.key 1 cipher BF-CBC #log-append /var/log/ovpn_$account.log EOF # remove old archive if exists [[ -f $ACCOUNTS_DIR/${account}.zip ]] && rm -f $ACCOUNTS_DIR/${account}.zip cd $ACCOUNTS_DIR # creating archive [[ -f `which zip 2>/dev/null` ]] && zip ${account}.zip -r $account # sending email [[ -f `which uuencode 2>/dev/null` ]] && uuencode ${account}.zip ${account}.zip | sendmail $MAIL_TO
Предполагается что AMT изначально активирован через UEFI (CTRL+P при загрузке, все доступные опции в ENABLE), а так же в web-интерфейсе (https, port 16692) используется выделенный IP.
Единственный NIC обслуживает как плату AMT, так и сеть хоста. При этом вы НИКАК не можете получить доступ из хостовой системы к AMT: одно из многочисленных проявлений security модели Intel, которое невозможно обойти.
Включение VNC производится только со стороннего компьютера, через WS-Management API. Для работы с ним я использовал клиент wsmancli, который присутствует в репозитории Ubuntu, но отсутствует в Debian.
К сожалению, по прошествии полугода уже не могу вспомнить ключи, передаваемые MEI CLI для активации http-интерфейса, но могу сказать точно: предоставляемая Intel версия CLI не работает с ядрами от Debian Squeeze/Wheezy, а качество исходников требует множества правок, экспериментов с версиями gcc и веселых упражнений с флагами компилятора.
В целом, активация VNC оказалась несколько нетривиальной задачей, т.к. на поддержку управления новыми версиями контроллера в Linux товарищи из Intel забили где-то в районе 2008-2009 года.
Для Debian Wheezy можно использовать следующий ubuntu-пакет и его зависимости:
Методом вдумчивого изучения документации к SDK AMT, был изготовлен следующий скрипт.
Основным затыком в процессе настройки стал пароль, который визуально соответствовал требованиям безопасности Intel и принимался API без ошибки - но настройки попросту не менялись.
It must be a strong password – exactly eight characters long, containing a capital letter, a lower case letter, a digit, and at least one 7-bit ASCII non alpha-numeric character above 32, (e.g. '!', '$', ';'). Note that “_” is considered alphanumeric. The password cannot contain the characters '"', ',', and ':'.
С описанием использованных параметров можно ознакомиться тут.
#!/usr/bin/env bash CIM=http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2 AMT=http://intel.com/wbem/wscim/1/amt-schema/1 IPS=http://intel.com/wbem/wscim/1/ips-schema/1 # configure parameter HOST=192.168.111.100 # admin password, defined through initial UEFI setup ADMIN_PW=yiexoob8Miup$ # password to access VNC remotely VNC_PW=VaeZ1reu4aizi$ auth="-h $HOST -P 16992 -u admin -p $ADMIN_PW" wsman put $IPS/IPS_KVMRedirectionSettingData $auth -k "SessionTimeout=10" -k "OptInPolicy=false" -k "RFBPassword=$VNC_PW" -k "Is5900PortEnabled=true" -k "RequestedState=2" # DEBUG: track changes #wsman get $IPS/IPS_KVMRedirectionSettingData $auth
Примеры копирования при использовании авторизации по ssh-ключам.
Закрывающий слеш в пути к исходной директории обязателен.
Задание представляет из себя текстовый файл.
lftp -f tasks.lftp
В пакете coreutils присутствуют GNU реализации ls и dircolors, что позволяет использовать привычные схемы подсветки.
# pkg install coreutils
alias grep="grep --color=auto" [[ -x `which gdircolors` ]] && eval "$(gdircolors -b)" || export LSCOLORS=ExGxFxdxCxDxDxhbadExEx [[ -x `which gls` ]] && alias ls="gls --color=auto" || alias ls="ls -G" [[ -x `which gsed` ]] && alias sed="gsed"
Подразумевается что в env уже есть
export PATH=~/bin/:$PATH
chmod +x ~/bin/tab
ln -s ~/bin/tab ~/bin/untab
1,my table,another field 2,my table,yet another field
ID,Name,Description 1,my table,another field 2,my table,yet another field
:'<,'>!tab
:'<,'>!untab
------------------------------------ | 1 | my table | another field | | 2 | my table | yet another field | ------------------------------------
cat csv-formatted.txt | tab
Лучи добра засылать сюда.
#!/usr/bin/env perl #=============================================================================== # # FILE: tab # # USAGE: "tab" or "untab" # # DESCRIPTION: This will turn comma seperated input from stdin into a text table. # It can also then convert it back if program is invoked as "untab". # # As well as being used on the command line, tab/untab can be # used from within vi, and can work on tables that are commented # out with # or //. # # OPTIONS: # ------------------------------------------------------------------------- # | Command/Option | Purpose | # |----------------|------------------------------------------------------| # | tab | Reads from stdin and tabulates comma seperated input | # | tab <-t> | Tabulates input and assumes first row are titles | # | tab <-h> | Prints this help | # | tab <-nb> | Tabulates without a border | # | tab <-fw X> | Wrap fields greater than X big don't break words | # | tab <-fs X> | Wrap fields greater than X big and break words | # | tab <-vp X> | Vertically pad table by X lines | # | tab <-hp X> | Horizontally pad fields by X chars | # | tab <-b X> | Tabulates with a border made from char X | # |----------------|------------------------------------------------------| # | untab | Reads from stdin and untabulates table input | # | untab <-b X> | Untabulate a table with border char X | # | untab <-nb> | Untabulate a borderless table | # ------------------------------------------------------------------------- # # REQUIREMENTS: --- # BUGS: --- # NOTES: --- # AUTHOR: Ben Staniford (BTS), <ben.staniford@g nospam mai l.com> # COMPANY: # VERSION: 1.0 # CREATED: 23/08/07 11:53:19 BST # REVISION: --- #=============================================================================== # TODO # 1. Make tab and untab keep existing indentation including inside comments # 2. Store the comment regexp only once in a global variable # 3. Allow facility to set the delimiter on the command line use strict; use warnings; #Default values (Normally set from cmd line) my $HPADDING=1; #How much horizontal padding my $VPADDING=0; #How much vertical padding my $VBORDER="|"; #What is our vertical border? my $HBORDER="-"; #What is our horizontal border/divider? my $wrapped_line_vpad=1; #Should we vertically pad fields that have been word wrapped? my $break_words_on_wrap=1; #Should we break words when wrapping my $field_wrap_boundary=0; #How big should a field be before we wrap it? #Globals my @max_field_sizes=(); my $max_col_count=0; my $comment_char=""; my $titles=0; #Funcs sub tabulate(); sub get_fields($); sub print_header_footer(); sub add_padding($); sub untabulate(); sub add_field_empty_space($$); sub print_usage(); sub wrap_oversized_fields(@); sub print_table_divider($); #No STDERR under any circumstances open (STDERR, ">/dev/null"); #Arguments my $args = join ' ', @ARGV; if ($args =~ /-t/) { $titles=1; } if ($args =~ /-nb/) { $VBORDER=""; $HBORDER=""; $HPADDING=2;} if ($args =~ /-b\s+(\S)/) { $VBORDER=$1; $HBORDER=$1; $HPADDING=1;} if ($args =~ /-fs\s+(\S+)/) { $field_wrap_boundary=$1; $break_words_on_wrap=0;} if ($args =~ /-fw\s+(\S+)/) { $field_wrap_boundary=$1; $break_words_on_wrap=1;} if ($args =~ /-vp\s+(\S+)/) { $VPADDING=$1} if ($args =~ /-hp\s+(\S+)/) { $HPADDING=$1} elsif ($args =~ /-h/) { print_usage(); exit 0; } #If we're invoked as "untab", i.e. via symlink, do the inverse of normal behavior #Note, untab uses most of the same program arguments above. chomp(my $PROGRAM_NAME = `basename $0`); if ($PROGRAM_NAME eq "untab") { untabulate(); } else { tabulate(); } exit 0; # ------------------------------------------------------------------ # | Name | Purpose | Parameters | # |--------------|------------------------------------|------------| # | tabulate() | Main function that tabulates stdin | | # ------------------------------------------------------------------ sub tabulate() { #Step 1, load the data into a list my @table=<STDIN>; #Step 2, If we have field length restrictions, reorder the table as #needed. Note, this can't be untabbed. if ($field_wrap_boundary != 0) { @table = wrap_oversized_fields(@table); } #Step 3, calculate the number of rows and columns from the input as well as the #maximum field size for each column. Also, work out if this table is in a comment. for my $line (@table) { chomp $line; my @fields = get_fields($line); my $counter=0; #Work out if the data is inside a comment if ($counter==0 && $line=~/^(\#|\/\/)/) { $comment_char=$1; } $line =~ s/^$comment_char//; for my $field (@fields) { if (!defined $max_field_sizes[$counter]) { $max_field_sizes[$counter] = 0; } if ($max_field_sizes[$counter] < length($field)) { $max_field_sizes[$counter] = length($field); } $counter++; } if ($counter > $max_col_count) { $max_col_count=$counter; } } #Step 4, print out the table print_header_footer(); my $lcounter=0; for my $line (@table) { chomp $line; my @fields = get_fields($line); if ($comment_char ne "") { print "$comment_char "; } if ($VBORDER ne "") { print $VBORDER.add_padding(" "); } $lcounter++; my $counter=0; #Print fields for my $field (@fields) { print "$field".add_field_empty_space(length($field), $counter).add_padding(" "); print $VBORDER.add_padding(" "); $counter++; } #Print any empty fields (if they exist) if ($counter < $max_col_count) { for (my $i=0;$i<($max_col_count - $counter);$i++) { print add_field_empty_space(0, $counter+$i).add_padding(" "); print $VBORDER.add_padding(" "); } } print "\n"; if ($VPADDING==1) { print_table_divider(" "); } if ($titles && $lcounter==1) { #print_header_footer(); print_table_divider($HBORDER); } } print_header_footer(); } # ----------------------------------------------------------------------------- # | Name | Purpose | Parameters | # |-----------------------|------------------------|--------------------------| # | print_table_divider() | Print out a divider in | Character divider should | # | | the table | made from | # ----------------------------------------------------------------------------- sub print_table_divider($) { my $divider_char = shift; if ($divider_char eq $HBORDER && $HBORDER eq "") { return; } if ($comment_char ne "") { print "$comment_char "; } for my $size (@max_field_sizes) { print $VBORDER.add_padding($divider_char); for (my $i=0;$i<$size;$i++) { print $divider_char; } print "".add_padding($divider_char); } print $VBORDER."\n"; } # ---------------------------------------------------------------------------- # | Name | Purpose | Parameters | # ---------------------------------------------------------------------------- # | print_header_footer() | Print out the tables header/footer | | # ---------------------------------------------------------------------------- sub print_header_footer() { my $divider_char = $HBORDER; if ($divider_char eq $HBORDER && $HBORDER eq "") { return; } if ($comment_char ne "") { print "$comment_char "; } for my $size (@max_field_sizes) { print $HBORDER.add_padding($divider_char); for (my $i=0;$i<$size;$i++) { print $divider_char; } print "".add_padding($divider_char); } print $HBORDER."\n"; } # ------------------------------------------------------------------------------ # | Name | Purpose | Parameters | # ------------------------------------------------------------------------------ # | add_field_empty_space() | Print out the field spacer | Field Length (int) | # | | | Field Number (int) | # ------------------------------------------------------------------------------ sub add_field_empty_space($$) { my $ret=""; my $field_length=shift; my $field_number=shift; my $empty_space_size=$max_field_sizes[$field_number] - $field_length; for (my $i=0;$i<$empty_space_size;$i++) { $ret.=" "; } return $ret; } # ----------------------------------------------------------------------------- # | Name | Purpose | Parameters | # |---------------|------------------------------|----------------------------| # | add_padding | Print out the padding string | Padding character (string) | # ----------------------------------------------------------------------------- sub add_padding($) { my $padding_char = shift; my $ret=""; for (my $i=0;$i<$HPADDING;$i++) { $ret.=$padding_char; } return $ret; } # ----------------------------------------------------------------------------- # | Name | Purpose | Parameters | # |--------------|--------------------------------------|---------------------| # | get_fields | Extract a list of fields from a line | Input line (string) | # ----------------------------------------------------------------------------- sub get_fields($) { my $line=shift; my @fields = split ',',$line; my @ret=(); for my $field (@fields) { $field =~ s/^\s*//; $field =~ s/\s*$//; push @ret, $field; } return @ret; } # ----------------------------------------------------------------------------------- # | Name | Purpose | Parameters | # |----------------|---------------------------------------------------|------------| # | untabulate() | Perform the inverse function and untabulate stdin | | # ----------------------------------------------------------------------------------- sub untabulate() { my $counter=0; while (<STDIN>) { chomp; #Work out if the data is inside a comment if ($counter==0 && $_=~/^(\#|\/\/)/) { $comment_char=$1; } #Handle a borderless table specifically if ($HBORDER eq "" && $VBORDER eq "") { s/\s{2,200}/,/g; s/,$//; #This is a table with a border } else { my $hb_regexp="\\$HBORDER"; my $vb_regexp="\\$VBORDER"; s/^$hb_regexp*$//g; s/^(?:$hb_regexp|$vb_regexp)*$//; s/^$comment_char\s*$hb_regexp*$//g; s/\s*$vb_regexp\s*/,/g; } s/^$comment_char\,/$comment_char/; for (my $i=0;$i<20;$i++) { s/^\,//; s/\,$//; } s/,/, /g; #If you want spaces as the default after commas if ($_ !~ /$comment_char\s/) { s/$comment_char/$comment_char /; } if ($_ !~ /^\s*$/) { print "$_\n"; } $counter++; } } # ---------------------------------------------------------------------------------------- # | Name | Purpose | Parameters | # |---------------------------|------------------------------------------|---------------| # | wrap_oversized_fields() | Wrap fields that are more than specified | List of lines | # | | size. This works by rewriting the | | # | | comma seperated data so that extra lines | | # | | are made. For this reason this | | # | | function cannot easily be undone by " | | # | | untab" | | # ---------------------------------------------------------------------------------------- sub wrap_oversized_fields(@) { my @table=@_; my @ret; #Go through each line in the table for my $line (@table) { my @overflow_buffer=(); chomp $line; my $lcounter=0; #Work out if the data is inside a comment if ($lcounter==0 && $line=~/^(\#|\/\/)/) { $comment_char=$1; } $line =~ s/^$comment_char//; my @fields = get_fields($line); my @overflow_fields = (); my $fcounter = 0; #Go through fields in each line looking for fields that must be split for my $field (@fields) { if (length($field) > $field_wrap_boundary) { my $temp; #Wrap and preserve words if ($break_words_on_wrap) { while ($field =~ /^(.{0,$field_wrap_boundary}\b)/) { $overflow_fields[$fcounter].=",$1"; $field=$'; } #Wrap and split words } else { while ($temp = substr($field, 0, $field_wrap_boundary)) { $temp =~ s/^\s*//; $overflow_fields[$fcounter].=",$temp"; $field=substr($field, $field_wrap_boundary,length($field)); } } } else { $overflow_fields[$fcounter]=$field; } $fcounter ++; } #Build the extra lines that must be put back into @table using the #@overflow_fields table $fcounter=0; my $keep_processing=1; while ($keep_processing) { $keep_processing=0; my $counter = 0; for (@overflow_fields) { my $field, my $remainder; if( ($field, $remainder) = /^,(.*?)(,.*)$/) { my $a=1; } else { $field=$_; $field=~s/^,//; } if ($field ne "") { $keep_processing = 1; } #Put any extra lines we make into the overflow buffer so that #that can be added into our return result. $overflow_buffer[$fcounter].=",$field"; $overflow_fields[$counter]=$remainder; $counter++; } $fcounter++; } #Put the contents of the overflow buffer into our return result for $line (@overflow_buffer) { #print "OB: $line\n"; $line =~ s/^,//; if ($line !~ /^,*$/) { push @ret, $line; } elsif ($wrapped_line_vpad==1) { push @ret, $line; } } $lcounter++; } return @ret; } sub print_usage() { print <<END; ------------------------------------------------------------------------- | Command/Option | Purpose | |----------------|------------------------------------------------------| | tab | Reads from stdin and tabulates comma seperated input | | tab <-t> | Tabulates input and assumes first row are titles | | tab <-h> | Prints this help | | tab <-nb> | Tabulates without a border | | tab <-fw X> | Wrap fields greater than X big don't break words | | tab <-fs X> | Wrap fields greater than X big and break words | | tab <-vp X> | Vertically pad table by X lines | | tab <-hp X> | Horizontally pad fields by X chars | | tab <-b X> | Tabulates with a border made from char X | |----------------|------------------------------------------------------| | untab | Reads from stdin and untabulates table input | | untab <-b X> | Untabulate a table with border char X | | untab <-nb> | Untabulate a borderless table | ------------------------------------------------------------------------- END }
Добавить в .pl-скрипт:
$ENV{PERL_NET_HTTPS_SSL_SOCKET_CLASS} = "Net::SSL"; $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; $ENV{HTTPS_VERSION} = '3'; $ENV{HTTPS_DEBUG} = 0;
Во избежание потенциальных проблем с удаленным обновлением ядра, я пользуюсь механизмом fallback, реализованном в grub уже довольно давно.
В данном случае используется grub2, принятый по умолчанию в Debian Wheezy.
Обязательные элементы конфига загрузчика:
GRUB_DEFAULT=saved GRUB_CMDLINE_LINUX_DEFAULT="panic=30"
В случае kernel panic сервер будет автоматически возвращен в последнее стабильное ядро. Мой конфиг загрузчика:
# grep ^[^#] /etc/default/grub GRUB_DEFAULT=saved GRUB_TIMEOUT=15 GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` GRUB_CMDLINE_LINUX_DEFAULT="intel_iommu=on panic=30" GRUB_CMDLINE_LINUX="" GRUB_DISABLE_OS_PROBER=true
Просматриваем доступные загрузчику ядра:
# grub-mkconfig 2>/dev/null | perl -ne 'print "$1\n" if m/^menuentry.+?'\''(.+?)'\''/' Debian GNU/Linux, with Linux 3.11.0-031100rc5-generic Debian GNU/Linux, with Linux 2.6.32-23-pve
Текущее ядро - стабильное, при проблемах мы вернемся именно в него:
# uname -rs Linux 2.6.32-23-pve
Выставляем его в fallback:
# grub-set-default 'Debian GNU/Linux, with Linux 2.6.32-23-pve'
Ядро 3.11-rc5 является релиз-кандидатом, но в нем на данный момент наиболее полно реализована поддержка новых чипсетов под процессоры Haswell.
Команда grub-reboot разрешит загрузиться этому ядру только один раз. Реальной перезагрузки не произойдет.
# grub-reboot 'Debian GNU/Linux, with Linux 3.11.0-031100rc5-generic'
Инсталляции Debian, произведенные не через debian-installer, зачастую не содержат в себе post-hook на перегенерацию initrd.
Поэтому выполняем его вручную:
# update-initramfs -k all -u
Обновляем конфиг загрузчика:
# update-grub2
Перезагружаем сервер в новое ядро:
# reboot
В случае успешной загрузки нового ядра сообщаем grub'у что теперь будем использовать обновленную версию:
# grub-set-default 'Debian GNU/Linux, with Linux 3.11.0-031100rc5-generic'
Все просто.
apt-get install tasksel aptitude install ~pstandard ~prequired ~pimportant -F%p
/etc/apt/apt.conf не должен содержать в себе упоминаний APT::Default-Release
/etc/apt/sources.list
deb http://mirror.yandex.ru/debian/ wheezy main contrib non-free deb http://mirror.yandex.ru/debian/ jessie main contrib non-free deb http://security.debian.org/ jessie/updates main contrib non-free
Для отката с testing до stable достаточно внести в /etc/apt/preferences следующие записи:
Package: * Pin: release a=stable Pin-Priority: 1001 Package: * Pin: release a=testing Pin-Priority: 900 Package: * Pin: release a=unstable Pin-Priority: 800 Package: * Pin: release o=Debian Pin-Priority: -1
Если команда apt-cache policy выдает правильные приоритеты, то поочередно выполняем apt-get upgrade и apt-get dist-upgrade, после чего мы остаемся на ветке stable.
Теперь можем добавить в /etc/apt/apt.conf строку APT::Default-Release "wheezy";