Stan baterii w laptopie – linux

Zaniepokoił mnie wskaźnik stanu naładowania baterii. Kilka godzin pracy na laptopie z podpiętym zasilaczem a 48% jak było tak było i nic nie chciało się ruszyć.

Polecenie:

cat /proc/acpi/battery/BAT1/info

Dało wynik:

present:                 yes
design capacity:         39960 mWh
last full capacity:      46320 mWh
battery technology:      rechargeable
design voltage:          11100 mV
design capacity warning: 420 mWh
design capacity low:     156 mWh
cycle count:              0
capacity granularity 1:  264 mWh
capacity granularity 2:  3780 mWh
model number:            PABAS024
serial number:           3658Q
battery type:            LION
OEM info:                LG

Czy to jest w ogóle możliwe aby projektowana pojemność baterii (design capacity) była mniejsza od ostatnio odnotowanej pełnej pojemności (last full capacity)? Mój laptop ma zaledwie dwa miesiące licząc od daty zakupu. Czy wartość pojemności projektowanej jest specjalnie zaniżana przez producentów, abym w przypadku sprawdzenia parametrów baterii – dajmy na to po roku użytkowania – czuł się bardziej komfortowo z powodu teoretycznie mniejszego zużycia baterii? A może te parametry są po prostu źle odczytywane?

Tak czy inaczej nie zmienia to faktu, że pomimo podłączonego zasilacza moja bateria zwyczajnie się nie ładowała. Pod Windowsem dostałem przynajmniej czytelny komunikat, natomiast widżet w KDE zwyczajnie mnie okłamywał. Jak już jesteśmy przy KDE to przy okazji zakupu nowego laptopa zdecydowałem się powrócić do KDE po zawodzie jaki mi sprawiło Unity. Znajomy zapewniał mnie, że Plasma została już dopracowana – NIE ZOSTAŁA.

Wracając jednak do baterii. Wykonałem kilkakrotnie polecenie:

cat /proc/acpi/battery/BAT1/state

Dało wynik:

present:                 yes
capacity state:          ok
charging state:          charged
present rate:            0 mW
remaining capacity:      22230 mWh
present voltage:         10924 mV

Wartość remaining capacity nie ulegała zmianie. Postanowiłem rozładować całkowicie baterię, a później spróbować ją naładować od zera. Czekając na rozładowanie baterii znalazłem i trochę zmodyfikowałem skrypcik w bash-u pokazujący stan baterii – (może się komuś przyda).

#!/bin/sh
 
CUR=`cat /proc/acpi/battery/BAT*/state | grep remaining | awk {'print $3'}`
STATE=`cat /proc/acpi/battery/BAT*/state | grep charging | awk {'print $3'}` 
MAX=`cat /proc/acpi/battery/BAT*/info | grep full | awk {'print $4'}`
DESIGN=`cat /proc/acpi/battery/BAT*/info | grep 'design capacity:' | awk {'print $3'}`
PRC=0
 
REAL_CAP=$(($MAX*100/$DESIGN))
PRC=$(($CUR*100/$MAX))
if [ $PRC -gt 100 ]; then
    PRC=100
fi 
 
echo 'State : '$STATE
echo 'Design Battery Capacity : '$DESIGN' (100%)'
echo 'Real Battery Capacity : '$MAX' ('$REAL_CAP'%)'
echo 'Current Battery capacity : '$CUR' ('$PRC'%)'

Po całkowitym rozładowaniu, przy wyłączonym komputerze podłączyłem zasilacz. Dioda zaczęła pokazywać, że bateria się ładuje. I rzeczywiście bateria naładowała mi się całkowicie. Nie jestem sprzętowcem i nie czytam fachowej prasy dlatego nie wiem czy to prawidłowe działanie – jakieś zabezpieczenie przed przedwczesnym zużyciem baterii czy też objaw uszkodzenia sprzętu? W innych laptopach, z którymi się spotkałem mogłem w każdej chwili doładować baterię.

Wydobywanie tekstów i grafik z plików PDF

Bywa że klient przysyła Ci treści do umieszczenia na stronie z krótkim komentarzem – „Tak to sobie wyobrażam”. Otwierasz maila i widzisz plik PDF. Są tam pięknie ułożone teksty okraszone kolorowymi fotografiami, wszystko elegancko poukładane i skomponowane, a Ty drapiesz się w głowę i nic nie mówisz bo szkoda słów. Jeśli jesteś webdeveloperem, specjalistą od cięcia i stylowania to szczerze Ci współczuję. Jeśli jednak Twoim jedynym zadaniem jest wydobycie z tego PDF-a wszystkich tekstów oraz grafik to jest nadzieja.

Klikacze lub marzyciele często patrzący w „okna” mogą skorzystać z jednej z rad proponowanych w artykule How to Extract Text from a PDF document lub How Can I Get Text or Images Out of a PDF File?. Alternatywą jest użycie konsoli i wierzcie mi w tym przypadku jest to o wiele wygodniejsze i szybsze rozwiązanie.

Do wyłuskania tekstów używamy programu „pdftotext” będącego częścią programu „xpdf

pdftotext ./dokument.pdf

Gdyby były problemy z polskimi literami warto zapoznać się z opcją „enc”:

pdftotext -enc Latin2 dokument.pdf

albo

pdftotext -enc UTF-8 dokument.pdf

Z obrazkami robimy identycznie tylko, że używając programu „pdfimages” także będącego konsolowym narzędziem „xpdf-a”

pdfimages ./dokument.pdf  przedrostek_obrazka

Program „pdfimages” zapisuje obrazki w formacie plików „ppm” więc trzeba je jeszcze przekonwertować do jpg-ów np. przy pomocy programu „pnmtojpeg” będącego częścią większego pakietu programów graficznych „Netpbm„.

for pic in *.ppm 
do 
    pnmtojpeg "${pic}" > "${pic/%ppm/jpg}" 
done

O ile programy „pdftotext” jak i „pdfimages” miałem już w systemie to „pnmtojpeg” trzeba było doinstalować i kiedy już to zrobiłem i przetestowałem przypomniałem sobie, że mam przecież zainstalowanego „ImageMagick-a„, którego użycie okazało się jeszcze prostsze.

mogrify -format jpg *.ppm

Pliki wynikowe uzyskane po zastosowaniu „mogrify” są większe co sugeruje mniejszą stratę na jakości, poza tym jak się ma „ImageMagick-a” to można z tymi plikami zrobić przy okazji dużo więcej np. automatycznie przeskalować, utworzyć miniatury, dodać ramki czy co nam tam jeszcze przyjdzie do głowy. Tworząc skrypt, który wszystkie wyżej przytoczone komendy zbiera w jedną zdecydowałem się właśnie na „mogrify”.

Plik extractpdf.sh

#!/bin/sh
 
if [ $# -lt 1 ]; then
    echo "Usage: `basename $0` file.pdf"
    exit 1;
fi
 
PDF=$1
FILE_NAME=`basename ${PDF%.*}`
TEMP_DIR="`dirname $PDF`/${FILE_NAME}"
 
if [ ! -e $TEMP_DIR ]; then
    mkdir -p $TEMP_DIR;
fi
pdftotext $PDF "${TEMP_DIR}/${FILE_NAME}.txt"
 
pdfimages $PDF "${TEMP_DIR}/${FILE_NAME}"
 
mogrify -format jpg ${TEMP_DIR}/*.ppm
find ${TEMP_DIR}/ -name "*.ppm" -exec rm {} \;

Skrypt oszczędza masę pisania poza tym jest uniwersalny więc nadaje się do wielokrotnego użytku. Teraz wystarczy nadać mu prawa do wykonywania

chmod +x ./extractpdf.sh

i cała praca to wywołanie skryptu z podaniem ścieżki do pliku pdf w parametrze

./extractpdf.sh ./dokument.pdf

Można pokusić się o rozbudowę tego skryptu o sprawdzanie czy wymagane programy są zainstalowane oraz zwiększyć funkcjonalność poprzez próbę użycia „pnmtojpeg” w przypadku jeśli „ImageMagick” nie jest zainstalowany.

Plik extractpdf2.sh

#!/bin/bash
 
if [ $# -lt 1 ]; then
    echo "Usage: `basename $0` file.pdf"
	exit 1;
fi
 
type -P pdftotext &>/dev/null || { echo "I require pdftotext but it's not installed.  Aborting." >&2; exit 1; }
 
type -P pdfimages &>/dev/null || { echo "I require pdfimages but it's not installed.  Aborting." >&2; exit 1; }
 
if type -P mogrify >/dev/null; then
    CONVERTER="mogrify"
else
    type -P pnmtojpeg &>/dev/null || { echo "I require the mogrify or pnmtojpeg but none of them is not installed.  Aborting." >&2; exit 1; } 
    CONVERTER="pnmtojpeg"
fi
 
PDF=$1
FILE_NAME=`basename ${PDF%.*}`
TEMP_DIR="`dirname $PDF`/${FILE_NAME}"
 
if [ ! -e $TEMP_DIR ]; then
    mkdir -p $TEMP_DIR;
fi
 
pdftotext $PDF "${TEMP_DIR}/${FILE_NAME}.txt"
 
pdfimages $PDF "${TEMP_DIR}/${FILE_NAME}"
 
if [ $CONVERTER = 'mogrify' ]; then
    mogrify -format jpg ${TEMP_DIR}/*.ppm
    find ${TEMP_DIR}/ -name "*.ppm" -exec rm {} \;
else
    for PIC in ${TEMP_DIR}/*.ppm
    do
        pnmtojpeg "${PIC}" > "${PIC/%ppm/jpg}"
        rm $PIC
    done
fi

UWAGA!!! Użycie „type -P” wymaga skorzystania konkretnie z powłoki „bash” gdyż w „sh” program „type” nie ma opcji „-P” i traktuje ją jak ścieżkę do pliku co kończy się komunikatem błędu (-P: not found). Dlatego pomimo, że plik dalej nazywa się extractpdf.sh to zamiast „#!/bin/sh” należy wpisać „#!/bin/bash”.

To oczywiście nie wyczerpuje naszych możliwości. Zaproponowane przeze mnie narzędzie to niezbędne minimum. Stworzenie tego skryptu kosztowało mnie trochę czasu ale jest to praca jednorazowa. Podobnie miałem ze skryptem do generowania miniatur za to obecnie stale mam go w swoim arsenale i wierzcie mi, że suma sumarum zaoszczędził mi już naprawdę wiele czasu.

Posted in Bash | Tagged byZbigniew Heintze

Przeskalowanie obrazków w katalogu

Pracując nad funkcjonalnością uploadu plików z możliwością ich wcześniejszego podglądu postanowiłem, że pliki nie będące obrazkami będą prezentowane za pomocą ikon odzwierciedlających ich rozszerzenie.

Ściągnąłem sobie z deviantarta [zestaw przykładowych ikon](http://fc07.deviantart.net/fs30/f/2008/064/4/5/4532f3c75d996fa7.rar). Bardzo fajne, kolorowe i duże obrazki. Stanąłem przed potrzebą przeskalowania wszystkich ikonek. Pierwsza myśl to poszukać przeglądarki zdjęć z możliwością masowej edycji plików. Chwilę później przypomniałem sobie, że mam zainstalowanego image magicka. 5 min i miałem już napisany prosty skrypcik w bashu, który tworzy podkatalog na miniatury, wyszukuje w bieżącym katalogu wszystkie pliki o zadanym rozszerzeniu i tworzy ich przeskalowane kopie.

#!/bin/sh
WIDTH=100
HEIGHT=50
EXT=png
THUMBDIR=./thumbnails-${WIDTH}x${HEIGHT}
 
mkdir $THUMBDIR
 
for IMG in `ls *.${EXT}`
do
	convert -resize ${WIDTH}x${HEIGHT} $IMG ${THUMBDIR}/$IMG
done

Automatyczna kopia bezpieczeństwa

Bezpieczeństwo danych to sprawa kluczowa. Jednym z ważniejszych zabiegów jest systematyczne tworzenie kopii bezpieczeństwa czyli tzw. backup. W ramach ćwiczeń w bashu postanowiłem napisać sobie taki mały skrypcik, który po odpaleniu przekopiuje cały katalog domowy mojego użytkownika na zewnętrzny dysk USB.

#!/bin/sh
 
#ustawienia sciezek
DEST_PATH="/path/to/my/external/disk"
BACKUP_DIR=$DEST_PATH/$(date +%Y-%m-%d-%H:%M)
SOURCE_PATH="/home/myuser"
 
#ustawienia domyslne
MODE="full"
TYPE="tar"
 
#wyswietlenie informacji jezeli bedzie mniej niz 2 argumenty.
if [ $# -lt 2 ]; then
    echo "Usage: `basename $0` <TAR|COPY> <FULL|incremental X days ago>"
fi
 
#jezeli podany jest drugi argument w linii polecen, to przystap do analizy
if [ ! -z "$2" ]; then
    case "$2" in
        FULL|full)
            MODE=full
            ;;
        *)
            MODE=$2
            ;;
    esac
fi
 
#jezeli pierwszy argument nie jest pusty do nalezy go przeanalizowac
if [ ! -z "$1" ]; then
    case "$1" in
        TAR|tar)
            TYPE=tar
            ;;
        copy|COPY)
            TYPE=copy
            ;;
    esac
fi
 
#jezeli katalog docelowy backupu nie istnieje, to nalezy go stworzyc
if [ ! -e $BACKUP_DIR ]; then
    mkdir -p $BACKUP_DIR;
fi
 
#funkcja robiaca backup za pomoca tara
make_tar_backup ()
{
    if [ "$MODE" = "full" ]; then
        echo "Full backup as archive TAR"
        tar -zcp -f $BACKUP_DIR/full.tgz $SOURCE_PATH
    else
        echo "Incremental backup as archive TAR. $MODE days ago"
        tar -zcp --newer-mtime "$MODE days ago" -f $BACKUP_DIR/incremental_$MODE.tgz $SOURCE_PATH
    fi
}
 
#funkcja robiaca backup za pomoca cp
make_copy_backup ()
{
    if [ "$MODE" = "full" ]; then
        echo "Full backup as save copy"
        for source_files in $SOURCE_PATH; do
            echo -e "\tDirectory $source_files"
            cp --parents -a $source_files $BACKUP_DIR
        done
    else
        echo "Incremental backup as save copy. $MODE days ago"
        for s in $SOURCE_PATH; do
            items_list=`find $s -ctime -$MODE`
            echo -e "\tDirectory $s"
            if [ ! -z "$items_list" ]; then
                for item_file in $lista; do
                    cp --parents -a $item_file $BACKUP_DIR
                done
            fi
        done
    fi
}
 
#start pomiaru czasu
time_start=$(date +%s);
 
#w zaleznosci od sposobu przechowywania backupu, uruchamiamy odpowiednie funkcje.
case "$TYPE" in
   tar)
      make_tar_backup
      ;;
   copy)
      make_copy_backup
      ;;
esac
 
time_end=$(date +%s);
exec_time=`expr $time_end - $time_start`
echo "Backup successfull. Execution time $exec_time seconds"

Proste ale działa 🙂

Bash-owe początki

Rzadko sięgam do Bash-a i zawsze, kiedy to robię muszę sobie wszystko przypominać od początku. No dobra – nie wszystko ;). Dzisiaj przeglądałem dysk i natknąłem się na mały programik, który kiedyś napisałem tak przy okazji. Pracowałem wtedy nad pewnym spider-em w pythonie i w ramach testów musiałem często kill-ować uruchomione przez tego „pajęczaka” procesy. Natchnęło mnie to wtedy do napisania prostego skryptu „killbyname” :D. Pamiętam, że jak na tak prostą funkcjonalność zajęło mi to wtedy zdecydowanie zbyt wiele czasu 😉

#!/bin/bash
# killbyname: Killing processes by name.
 
E_BADARGS=66
 
if test -z "$1"  # No command line arg supplied?
then
  echo "Usage: `basename $0` Process_to_kill"
  exit $E_BADARGS
fi
 
PROCESS_NAME="$1"
 
echo "Do you want kill processes:"
ps ax | grep "$PROCESS_NAME"
read -p "Yes (y) or No (n): " CONFIRM
 
if [ $CONFIRM = 'y' ]
then
    ps ax | grep "$PROCESS_NAME" | awk '{print $1}' | xargs -i kill {} 2&>/dev/null
fi
exit $?

W ramach ćwiczeń popełniłem też skrypt usuwający katalogi svn-a z projektu. Aż wstyd się przyznać ale pisząc to nie wiedziałem jeszcze, że istnieje coś takiego jak ***svn export***.

#!/bin/bash
# rmsvn
current_path=`pwd`
echo "Czy na pewno chcesz z katalogu $current_path \
 usunąć wszystkie podkatalogi .svn wraz z zawartością?"
echo "Potwierdź [y] lub anuluj [n]"
read confirmation
if [ $confirmation = 'y' ]
then
    find $current_path -name "\.svn" | xargs rm -rf
	if [ $? = 0 ]
	then
	    echo "Polecenie zostało wykonane."
    else
	    echo "Wykonanie polecenia się nie powiodło!"
	fi
else
    echo "Polecenie zostało anulowane."
fi

Jak już jesteśmy przy svn-ie to najczęściej okazuje się, że na serwerze produkcyjnym nie ma możliwości skorzystania z niego. Do tego jeszcze zdarzają się klienci kombinatorzy próbujący samodzielnie dokonywać zmian w projekcie. Aktualizacja plików w takiej sytuacji sprowadza się do ręcznego porównania katalogów z wersją live i dev. Kdiff ułatwia znalezienie plików różniących się od siebie, ale brakuje narzędzia ułatwiającego wyodrębnienie wyżej wspomnianych z całego projektu. Z tego właśnie powodu podjąłem się zadania napisania skryptu porównującego dwie wersje projektu i kopiujące do katalogu update tylko te pliki z nowej wersji, które różnią się od odpowiadających im plików starej wersji. Struktura katalogów zostaje zachowana. Programik jest bardzo prosty i bynajmniej nie niezawodny, ale przydał się kilka razy.

#!/bin/bash
# makeupdate
 
if [ $# -lt 2 || $1 = $2 ]
then
    echo "Usage: `basename $0` dir_with_old_version dir_with_new_vesion"
    exit
fi
 
OLD_DIR="$1"
NEW_DIR="$2"
 
UPDATE_DIR="./update"
mkdir $UPDATE_DIR
 
FILES_LIST=`diff -rqPx '.*' $OLD_DIR $NEW_DIR | awk '{print $4}'`
for FILE_PATH in $FILES_LIST
do
   DIR_PTH=`echo $FILE_PATH | sed -r 's/\/[a-Z0-9_]{1,}\.[a-z0-9]*//g'`
   mkdir -p $UPDATE_DIR/$DIR_PTH
   cp $FILE_PATH $UPDATE_DIR/$DIR_PTH
done
 
exit $?
Posted in Bash | Tagged byZbigniew Heintze