{"id":94,"date":"2012-12-08T14:29:53","date_gmt":"2012-12-08T13:29:53","guid":{"rendered":"https:\/\/caipirinha.spdns.org\/wp\/?p=94"},"modified":"2019-10-01T23:36:01","modified_gmt":"2019-10-01T21:36:01","slug":"admin-skripte","status":"publish","type":"post","link":"https:\/\/caipirinha.spdns.org\/wp\/?p=94","title":{"rendered":"Admin-Skripte"},"content":{"rendered":"\n<p>Auf dieser Seite gibt es verschiedene Skripte, welche ich auf dem\n Caipirinha-Server einsetze, um anfallende Verwaltungsaufgaben zu l\u00f6sen.\n Diese Skripte sollen als Anregung zur Erstellung eigener Skripte \ndienen, k\u00f6nnen aber nat\u00fcrlich auch komplett \u00fcbernommen und bei Bedarf \nangepasst werden. Es finden sich hier:\n<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Nach dem Booten<\/h2>\n\n\n\n<p>Dieses Skript f\u00fchre ich als <em>root<\/em> nach einem Booten der Maschine durch. Es macht folgende Dinge:\n<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Das Akustik-Management der Festplatten wird auf &#8220;Performance&#8221; gestellt (sprich: &#8220;Geschwindigkeit&#8221; statt &#8220;Ruhe&#8221;).<\/li><li>F\u00fcr einige Festplatten wird ein automatischer Ruhezustand \neingestellt. Die Systemplatten sollen aber nicht abschalten \n(Dauerbetrieb).<\/li><li>Die Festplatten mit Videos (<strong>\/home\/public\/Video<\/strong>) wird eingebunden. Dies erfolgt nicht gleich beim Start, weil diese Platte in die verschl\u00fcsselte Partition <strong>\/home\/public<\/strong> eingebunden wird.<\/li><li>Der <a href=\"http:\/\/localhost\/mediawiki\/index.php\/SNMP\">snmp<\/a>&#8211;\n und der snmptrap-Dienst wird gestartet. Der snmp-Dienst wird erst nach \ndem Einbinden der Video-Festplatten gestartet, weil snmp auch die \nPlattenauslastung \u00fcberwachen soll, und erst nach dem Einbinden der \nVideo-Festplatten alle snmp-Variablen verf\u00fcgbar sind.<\/li><li><a href=\"http:\/\/localhost\/mediawiki\/index.php\/MRTG\">mrtg<\/a> wird gestartet, um Netzwerk-Verkehr und CPU-Auslastung zu \u00fcberwachen.<\/li><li>Der sensor-Dienst wird gestartet, um die Temperatur im Server zu \u00fcberwachen.<\/li><li>Ein VLC-Server mit Telnet-Interface wird f\u00fcr die <a href=\"http:\/\/localhost\/mediawiki\/index.php\/Caipithek\">Caipithek<\/a> gestartet. Dabei muss nat\u00fcrlich <strong>geheimes_passwort<\/strong> durch ein selbst gew\u00e4hltes, geheimes Passwort ersetzt werden.<\/li><li>Ein <a href=\"http:\/\/localhost\/mediawiki\/index.php\/DLNA-Server\">DLNA-Server<\/a> wird mit dem Programm <strong>minidlna<\/strong> gestartet.<\/li><li><a href=\"http:\/\/localhost\/mediawiki\/index.php?title=OpenVPN&amp;action=edit&amp;redlink=1\">openVPN<\/a> wird gestartet und gleich danach noch <a href=\"http:\/\/localhost\/mediawiki\/index.php\/MySQL\">MySQL<\/a>. Der Grund daf\u00fcr ist, dass der <a href=\"http:\/\/localhost\/mediawiki\/index.php\/MySQL\">MySQL<\/a>-Server auf dem Caipirinha-Server als Slave Server des <a href=\"http:\/\/localhost\/mediawiki\/index.php\/MySQL\">MySQL<\/a>-Servers auf <a href=\"http:\/\/rueeck.name\">rueeck.name<\/a> l\u00e4uft, und die Verbindung \u00fcber <a href=\"http:\/\/localhost\/mediawiki\/index.php?title=OpenVPN&amp;action=edit&amp;redlink=1\">openVPN<\/a> getunnelt wird.<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">#! \/bin\/bash\n#\n# This script contains some commands that shall be executed after the\n# caipirinha server has booted up.\n#\n# Gabriel R\u00fceck 13.09.2010\n#\n\n# Configure power and acustic management of the hard disks.\nhdparm -S   0 \/dev\/sda\nhdparm -S   0 \/dev\/sdb\nhdparm -S 180 \/dev\/sdc\nhdparm -S 180 \/dev\/sdd\nhdparm -S 180 \/dev\/sde\nhdparm -M 254 \/dev\/sda\nhdparm -M 254 \/dev\/sdb\nhdparm -M 254 \/dev\/sdc\nhdparm -M 254 \/dev\/sdd\nhdparm -M 254 \/dev\/sde\n\n# Mount Video Array\nmount \/dev\/md3 \/home\/public\/Video\n\n# Start SNMP Services (must only be started after mounting \/home\/public\/Video)\n\/etc\/init.d\/snmpd start\nsnmptrapd\n\n# Start mrtg\ntouch \/var\/log\/mrtg.log \/var\/run\/mrtg.pid\nchown wwwrun:www \/var\/log\/mrtg.log \/var\/run\/mrtg.pid\nenv LANG=C mrtg --user wwwrun --group www --logging \/var\/log\/mrtg.log --lock-file \/var\/tmp\/mrtg --pid-file=\/var\/run\/mrtg.pid \/etc\/mrtg.conf\n\n# Start the sensor daemon\nrm \/var\/log\/sensord.rrd 2&gt;\/dev\/null\nmodprobe coretemp it87\nsensord -r \/var\/log\/sensord.rrd -p \/var\/run\/sensord.pid\nchmod a+r \/var\/log\/sensord.rrd\n\n# Start cvlc for the Caipithek\nsu -l wwwrun -c 'rm c*.log; cvlc -I oldtelnet --telnet-password geheimes_passwort &gt; cvlc.log 2&gt;&amp;1 &amp;'\n\n# Start DLNA Server (minidlna)\nsu -l wwwrun -c '\/usr\/sbin\/minidlna'\n\n# Start openVPN and mysql\n\/etc\/init.d\/openvpn start\n\/etc\/init.d\/mysql start<\/pre>\n\n\n\n<p>Wahrscheinlich k\u00f6nnte man dieses Skript auch automatisch nach dem \nAbschluss des Boot-Vorgangs ausf\u00fchren lassen. Falls jemand eine \nentsprechende Idee hat, bin ich f\u00fcr Hinweise dankbar.\n<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Neue Dateien auflisten lassen<\/h2>\n\n\n\n<p>Da verschiedene Benutzer des Caipirinha-Servers Schreibberechtigung \nauf dessen \u00f6ffentliche Ordner haben, verliere ich oft selbst den \n\u00dcberblick dar\u00fcber, welche Dateien wo neu abgelegt sind. Au\u00dferdem ist es \nschwierig, andere Benutzer \u00fcber neu abgelegte Dateien zu informieren. \nDas soll nun das folgende Skript machen, welches einen RSS-Feed erzeugt,\n der dann mit modernen Browsern oder Mail-Clients oder RSS-Clients \nlesbar ist. \u00dcber einen cron-Job wird dieses Skript einmal pro Nacht \nausgef\u00fchrt und erzeugt dann einen neuen RSS-Feed, den andere Benutzer \neinbinden k\u00f6nnen. Was ein RSS-Feed ist und wie er aufgebaut ist, wird \nauf <a href=\"http:\/\/cyber.law.harvard.edu\/rss\/rss.html\">[1]<\/a> beschrieben.\n<\/p>\n\n\n\n<p><strong>update_rss.sh<\/strong>:\n<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/bin\/bash\n#\n# This script searches various folders for new files, extracts a description of the files and generates an RSS 2.0 feed in XML.\n#\n# Gabriel R\u00fceck, gabriel@caipirinha.homelinux.org, 10.10.2012\n#\n\n# Pre-define some variables and read the configuration files.\numask 0022\nreadonly GENERATOR='Caipirinha RSS Generator'\nreadonly CONFIGPATH='\/etc\/rss'\n         DURATION=7\n         CHANNEL_NAME=$(hostname)\n         CHANNEL_LINK=\"http:\/\/$(hostname --fqdn)\/\"\n         TMPFILE='\/tmp\/rss'$RANDOM\n\n# Add the PATH variable so that it is the same whether the program is called from the shell or from within the cron environment.\nPATH='\/usr\/bin:\/bin:\/opt\/gnome\/bin'\n\n# Get additional options, if available\nwhile getopts&nbsp;:D:o:p:t:T: OPT\ndo case \"$OPT\" in\n     \"D\") OPT_DESCRIPTION=$OPTARG;;\n     \"o\") if [&nbsp;! -f $OPTARG ]; then\n             echo -e \"ERROR: The configuration file \\\"\"$OPTARG\"\\\" does not exist.\\n\"\n             exit 2\n          else\n             CONFIGFILE=$OPTARG\n          fi;;\n     \"p\") OPT_PATHFILE=$OPTARG;;\n     \"t\") OPT_DURATION=$OPTARG;;\n     \"T\") OPT_TITLE=$OPTARG;;\n   esac\ndone\n\n# Read the configuration file. If no configuration file has been specified, try to read \"\/etc\/rss\/rss.conf\".\n# However, there will not be an error message if no configuration file is available.\ntest -e ${CONFIGFILE:=$CONFIGPATH'\/rss.conf'} &amp;&amp; . $CONFIGFILE\n\n# Process optional arguments; they have precedence over the values defined in the configuration files.\ntest -n \"$OPT_DESCRIPTION\" &amp;&amp; DESCRIPTION=$OPT_DESCRIPTION\ntest -n \"$OPT_DURATION\" &amp;&amp; DURATION=$OPT_DURATION\ntest -n \"$OPT_PATHFILE\" &amp;&amp; PATH_FILE=$OPT_PATHFILE\ntest -n \"$OPT_TITLE\" &amp;&amp; TITLE=$OPT_TITLE\n\n# Check if sufficient arguments have been provided.\nshift $[$OPTIND-1]\nif [ $# -lt 1 ]; then\n   echo -e \"Usage:  \"$0\"  [OPTIONS]  DST_FILE_1  [DST_FILE_2  [...]]\\n\"\n   exit 1\nfi\n\n# Check if PATH_FILE exists.\nif [&nbsp;! -f $PATH_FILE ]; then\n   echo -e \"ERROR: The path file \\\"\"$PATH_FILE\"\\\" does not exist.\\n\"\n   exit 2\nfi\n\n# Get the lower link bar which has links to all subfolders that are available on the server.\n# As the pipe (|) creates a subshell, the while loop has to be located in () and has to have an echo command at the end which will then\n# send the accumulated variable back to the calling shell. That may look strange, but otherwise, things will not work... Bad trap for newbies...\n# Create a footer that contains links to all folders that shall be searched, with some CSS-style formatting, actuallz oriented towards www.faz.net\nFINAL='&lt;div style=\"margin:5px 0 5px 0; border-top:1px solid blue; font:9px arial;\"&gt;&lt;a href=\"'$CHANNEL_LINK'\"&gt;'$CHANNEL_NAME'&lt;\/a&gt; '\\\n$(sed '\/^ *#.*\/d' $PATH_FILE | (while read LINE;\n                                do HTML_PATH=$(echo $LINE | cut -f2 -d\"|\")\n                                   DESCRIPTION=$(echo $LINE | cut -f3 -d\"|\")\n                                   FINAL=$FINAL'| &lt;a href=\"'$HTML_PATH\/'\"&gt;'$DESCRIPTION'&lt;\/a&gt; '\n                                done;\n                                echo $FINAL;))'&lt;\/div&gt;'\n\n# Make the file readable for everyone\numask 022\n\n# Create page headers for the RSS file\necho '&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;' &gt; $TMPFILE\necho '&lt;rss version=\"2.0\" xmlns:atom=\"http:\/\/www.w3.org\/2005\/Atom\"&gt;' &gt;&gt; $TMPFILE\necho '&lt;channel&gt;' &gt;&gt; $TMPFILE\necho \" &lt;title&gt;$TITLE&lt;\/title&gt;\" &gt;&gt; $TMPFILE\necho \" &lt;link&gt;$CHANNEL_LINK&lt;\/link&gt;\" &gt;&gt; $TMPFILE\necho \" &lt;description&gt;$DESCRIPTION&lt;\/description&gt;\" &gt;&gt; $TMPFILE\necho \" &lt;managingEditor&gt;$EDITOR&lt;\/managingEditor&gt;\" &gt;&gt; $TMPFILE\necho \" &lt;generator&gt;$GENERATOR&lt;\/generator&gt;\" &gt;&gt; $TMPFILE\necho ' &lt;pubDate&gt;'$(date -R)'&lt;\/pubDate&gt;' &gt;&gt; $TMPFILE\n# Put an image of the server on the headline.\necho ' &lt;image&gt;' &gt;&gt; $TMPFILE\necho \"  &lt;title&gt;$TITLE&lt;\/title&gt;\" &gt;&gt; $TMPFILE\necho \"  &lt;url&gt;$IMG_URL&lt;\/url&gt;\" &gt;&gt; $TMPFILE\necho \"  &lt;link&gt;$CHANNEL_LINK&lt;\/link&gt;\" &gt;&gt; $TMPFILE\necho ' &lt;\/image&gt;' &gt;&gt; $TMPFILE\n\n# Scan all folders on whether there are new files. Extract the file name, create a link on it, get a description of the file, the date of the\n# last modification, and extract an icon from the Apache2 icons.\nsed '\/^ *#.*\/d' $PATH_FILE | while read LINE;\n     do SEARCH_PATH=$(echo $LINE | cut -f1 -d\"|\")\n        HTML_PATH=$(echo $LINE | cut -f2 -d\"|\")\n OMIT_PATH=$(echo $LINE | cut -f4 -d\"|\")\n        # The \"cd\" command must be connected with the \"find\" command because otherwise, if the \"cd\" path did not exist, the script would search the entire users's home\n        # directory and deliver sensitive information with the file names listed.\n cd \"$SEARCH_PATH\" &amp;&amp; find -L -not -path \"$OMIT_PATH\" -type f -mtime -$DURATION -perm -004 -name \"[[:alnum:]]*\" -not -name \"*~\" -not -name \"*.old\" -not -name \"metadata.xml\" -not -path \"*\/\\.*\" -print 2&gt;\/dev\/null |\n             # The following commands will be executed in a subshell; they would anyway because they follow the pipe (|) symbol.\n             # But first the variable IFS is set to \"|\" as separator. Normally, IFS is set to \" \". This is important for the read command as IFS\n             # contains the character that is used as a separator for the read command. A \" \" as separator leads to problems when the file name has\n             # a double white space like \"  \" or so in the name as read would report this back as a single white space \" \". That&nbsp;!$#% cost me a day...\n             (OLD_IFS=$IFS\n              IFS=\"\"\n              while read -r NAME;\n              do LINK_NAME=$(echo $NAME | sed -f $CONFIGPATH\/link_name.sed)\n                 HTML_NAME=$(basename $NAME | sed -f $CONFIGPATH\/html_name.sed)\n                 FILE_TYPE_KNOWN=false\n                 # Try first to determine the file type with the \"file\" command as sometimes, this yields the more exact result.\n                 FILE_TYPE=$(file -b $NAME)\n                 case \"$FILE_TYPE\" in\n                   \"ASCII text\")                  FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/txt.png\"&gt; '; FILE_TYPE_KNOWN=true;;\n                   *\"perl script\"*)               FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/source_pl.png\"&gt; '; FILE_TYPE_KNOWN=true;;\n                   *\"shell script\"*)              FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/shellscript.png\"&gt; '; FILE_TYPE_KNOWN=true;;\n                   \"vCard\"*)                      FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/vcalendar.png\"&gt; '; FILE_TYPE_KNOWN=true;;\n                 esac\n                 if&nbsp;! $FILE_TYPE_KNOWN; then\n                    # If the file type could not be determined with the \"file\" command, then proceed with \"gnomeinfo-vfs\".\n                    FILE_TYPE=$(gnomevfs-info $NAME | sed -n 's\/\\(^MIME type *:\\) \\(.*\\)\/\\2\/p')\n                    # unset $FILE_DESC because there may be old content in it.\n                    unset FILE_DESC\n                    case \"$FILE_TYPE\" in\n                      \"application\/msaccess\")                                           FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/database.png\"&gt; ';;\n                      \"application\/msword\")                                             FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/wordprocessing.png\"&gt; ';;\n                      \"application\/octet-stream\")                                       FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/binary.png\"&gt; ';;\n                      \"application\/pdf\")                                                FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/pdf.png\"&gt; ';;\n                      \"application\/rtf\")                                                FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/document.png\"&gt; ';;\n                      \"application\/vnd.ms-excel\")                                       FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/spreadsheet.png\"&gt; ';;\n                      \"application\/vnd.ms-outlook\")                                     FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/message.png\"&gt; ';;\n                      \"application\/vnd.ms-project\")                                     FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/txt2.png\"&gt; ';;\n                      \"application\/vnd.ms-powerpoint\")                                  FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/presentation.png\"&gt; ';;\n                      \"application\/vnd.openxmlformats-officedocument.presentation\"*)    FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/presentation.png\"&gt; ';;\n                      \"application\/vnd.openxmlformats-officedocument.spreadsheet\"*)     FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/spreadsheet.png\"&gt; ';;\n                      \"application\/vnd.openxmlformats-officedocument.wordprocessing\"*)  FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/wordprocessing.png\"&gt; ';;\n                      \"application\/vnd.oasis.opendocument.spreadsheet\")                 FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/spreadsheet.png\"&gt; ';;\n                      \"application\/vnd.oasis.opendocument.text\")                        FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/wordprocessing.png\"&gt; ';;\n                      \"application\/x-bittorrent\")                                       FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/torrent.png\"&gt; ';;\n                      \"application\/x-cd-image\")                                         FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/cdimage.png\"&gt; ';;\n                      \"application\/x-compressed-tar\")                                   FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/tgz.png\"&gt; ';;\n                      \"application\/x-font-speedo\")                                      FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/font.png\"&gt; ';;\n                      \"application\/x-font-ttf\")                                         FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/font_truetype.png\"&gt; ';;\n                      \"application\/x-font-type1\")                                       FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/font_type1.png\"&gt; ';;\n                      \"application\/x-java-archive\")                                     FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/source_java.png\"&gt; ';;\n                      \"application\/x-ms-dos-executable\")                                FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/binary.png\"&gt; ';;\n                      \"application\/x-msi\")                                              FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/make.png\"&gt; ';;\n                      \"application\/x-rpm\")                                              FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/rpm.png\"&gt; ';;\n                      \"application\/x-subrip\")                                           FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/txt2.png\"&gt; ';;\n                      \"application\/x-509\"*)                                             FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/encrypted.png\"&gt; ';;\n                      \"application\/xml\")                                                FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/html.png\"&gt; ';;\n                      \"application\/zip\")                                                FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/zip.png\"&gt; ';;\n                      \"audio\/midi\")                                                     FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/midi.png\"&gt; ';;\n                      \"audio\/\"*)                                                        FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/sound.png\"&gt; ';;\n                      \"image\/\"*)                                                        FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/image.png\"&gt; ';;\n                      \"text\/calendar\")                                                  FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/vcalendar.png\"&gt; ';;\n                      \"text\/csv\")                                                       FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/spreadsheet.png\"&gt; ';;\n                      \"text\/html\")                                                      FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/html.png\"&gt; ';;\n                      \"text\/plain\")                                                     FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/txt.png\"&gt; ';;\n                      \"text\/x-chdr\")                                                    FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/source_h.png\"&gt; ';;\n                      \"text\/x-c++hdr\")                                                  FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/source_h.png\"&gt; ';;\n                      \"text\/x-csrc\")                                                    FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/source_c.png\"&gt; ';;\n                      \"text\/x-c++src\")                                                  FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/source_c.png\"&gt; ';;\n                      \"text\/x-log\")                                                     FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/widget_doc.png\"&gt; ';;\n                      \"text\/x-uri\")                                                     FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/html.png\"&gt; ';;\n                      \"video\/quicktime\")                                                FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/quicktime.png\"&gt; ';;\n                      \"video\/mp\"*)                                                      FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/video.png\"&gt; ';;\n                      \"video\/x-\"*)                                                      FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/video.png\"&gt; ';;\n                      *)                                                                FILE_DESC='&lt;img src=\"'${CHANNEL_LINK}'kde-icons\/unknown.png\"&gt; ';;\n                    esac\n                 fi\n\n                 # Add the file description to the selected image.\n                 if [ ${FILE_TYPE%%\/*} = \"audio\" ]; then\n                    DATA=$(mediainfo -f \"$NAME\")\n                    MEDIA_DURATION=$(echo $DATA | sed -n 's\/^Duration[^:]*:[^0-9]*\\([0-9].*[^0-9].*\\)\/\\1\/p' | head -n1)\n                    FILE_DESC=\"$FILE_DESC $FILE_TYPE $MEDIA_DURATION, \"$(stat -c%s\" Bytes\" $NAME)\n                 elif [ ${FILE_TYPE%%\/*} = \"video\" ]; then\n                    DATA=$(mediainfo -f \"$NAME\")\n                    MEDIA_WIDTH=$(echo $DATA | sed -n 's\/^Width[^:]*:[^0-9]*\\([0-9].*\\)\/\\1\/p' | head -n1)\n                    MEDIA_HEIGHT=$(echo $DATA | sed -n 's\/^Height[^:]*:[^0-9]*\\([0-9].*\\)\/\\1\/p' | head -n1)\n                    MEDIA_DURATION=$(echo $DATA | sed -n 's\/^Duration[^:]*:[^0-9]*\\([0-9].*[^0-9].*\\)\/\\1\/p' | head -n1)\n                    VIDEO_STREAMS=$(echo $DATA | sed -n 's\/^Count of video streams[^:]*:[^0-9]*\\([0-9].*\\)\/\\1\/p' | head -n1)\n                    AUDIO_STREAMS=$(echo $DATA | sed -n 's\/^Count of audio streams[^:]*:[^0-9]*\\([0-9].*\\)\/\\1\/p' | head -n1)\n                    FILE_DESC=\"$FILE_DESC $FILE_TYPE ${MEDIA_WIDTH}x${MEDIA_HEIGHT}, $MEDIA_DURATION, $VIDEO_STREAMS video streams, $AUDIO_STREAMS audio streams, \"$(stat -c%s\" Bytes\" $NAME)\n                 else\n                    FILE_DESC=\"$FILE_DESC $FILE_TYPE, \"$(stat -c%s\" Bytes\" $NAME)\n                 fi\n                 # Create a new item for each newly found file.\n                 echo ' &lt;item&gt;' &gt;&gt; $TMPFILE\n                 echo '  &lt;title&gt;'$HTML_NAME'&lt;\/title&gt;' &gt;&gt; $TMPFILE\n                 echo '  &lt;link&gt;'$HTML_PATH\/$LINK_NAME'&lt;\/link&gt;' &gt;&gt; $TMPFILE\n                 echo '  &lt;pubDate&gt;'$(date -Rr $NAME)'&lt;\/pubDate&gt;' &gt;&gt; $TMPFILE\n                 echo '  &lt;description&gt;'$FILE_DESC$FINAL'&lt;\/description&gt;' &gt;&gt; $TMPFILE\n                 echo '  &lt;guid&gt;'$HTML_PATH\/$LINK_NAME'&lt;\/guid&gt;' &gt;&gt; $TMPFILE\n                 echo ' &lt;\/item&gt;' &gt;&gt; $TMPFILE\n              done;\n              # Reset IFS to its old value\n              IFS=$OLD_IFS)\n     done;\necho '&lt;\/channel&gt;' &gt;&gt; $TMPFILE\necho '&lt;\/rss&gt;' &gt;&gt; $TMPFILE\n\n# Move the file from the TMP folder to the final destinations.\nfor i in $*; do\n    cp $TMPFILE $i\ndone\nrm $TMPFILE<\/pre>\n\n\n\n<p>Leider funktioniert dieses Skript nicht ganz allein, sondern ben\u00f6tigt\n noch mehrere Hilfsdateien, was die Anwendung erschwert. In <strong>\/etc\/rss<\/strong> sollten folgende vier Dateien abgelegt werden:\n<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>\/etc\/rss\/link_name.sed<\/li><li>\/etc\/rss\/html_name.sed<\/li><li>\/etc\/rss\/rss.conf<\/li><\/ul>\n\n\n\n<p> Die sed-Hilfsdateien werden im Browser leider nicht richtig wieder gegeben. Deshalb kann man sie als Archiv unter <a href=\"ftp:\/\/rueeck.name\/download\/sed-Skripte.tgz\">[2]<\/a> herunter laden. Sie werden f\u00fcr die <strong>sed<\/strong>-Aufrufe im Skript ben\u00f6tigt. <\/p>\n\n\n\n<p>Die vierte Hilfsdatei ist hier abgedruckt:\n<\/p>\n\n\n\n<p><strong>\/etc\/rss\/rss.conf<\/strong>:\n<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># CONFIGURATION FILE FOR THE RSS SCRIPT\n# This File will be read by the RSS script. The settings in this file are the general settings for the script.\n#\n# General Settings for the RSS Script\n#\nTITLE=\"New Files on CAIPIRINHA\"\nCHANNEL_NAME=\"CAIPIRINHA Server\"\nCHANNEL_LINK=\"http:\/\/caipirinha.homelinux.org\/\"\nDESCRIPTION=\"Photographs, Music, Books and other Documents\"\nEDITOR=\"gabriel@caipirinha.homelinux.org (Gabriel R\u00fceck)\"\n#\n# Settings for the Image of the Website\n#\nIMG_URL=\"http:\/\/caipirinha.homelinux.org\/jpg\/Caipirinha.jpg\"\n#\n# Settings for the Path File (containing all paths that shall be searched and their respective HTML links)\nPATH_FILE=\"\/home\/public\/paths.txt\"\n#\n# Miscellaneous Settings\n#\n# Duration sets the number of days for the \"find\" command. Files which were modified up to $DURATION days, will be\n# taken into account.\n#\nDURATION=30<\/pre>\n\n\n\n<p>Die ersten beiden Dateien beschreiben Ersetzungen, welche das mehrfach eingesetzte <strong>sed<\/strong>-Kommando\n im Skript vornehmen soll. Ein RSS-Feed ist ja eine XML-Datei, und \ndeshalb m\u00fcssen bei den auf dem Caipirinha-Server vorkommenden \nDateinamen, welche ja im Idealfall beliebige Zeichen enthalten d\u00fcrfen, \nzahlreiche Ersetzungen vorgenommen werden, um den Eigenheiten von XML \nund HTML gerecht zu werden.\n<\/p>\n\n\n\n<p>Die dritte Datei ist eine Standardkonfiguration, welche \nverschiedene Parameter des RSS-Feeds (beispielsweise den Link zum \nPiktogramm des RSS-Feeds) festlegt. Alle in dieser \nStandard-Konfiguration angegebenen Werte k\u00f6nnen aber auch durch eine \neigene Konfigurationsdatei \u00fcberschrieben werden. Eine solche \nmodifizierte Konfigurationsdatei ist hier abgedruckt:\n<\/p>\n\n\n\n<p><strong>Eigene Konfigurationsdatei<\/strong>:\n<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># CONFIGURATION FILE FOR THE RSS SCRIPT\n# This File will be read by the RSS script. The settings in this file are the general settings for the script.\n#\n# General Settings for the RSS Script\n#\nTITLE=\"Gabriel R\u00fceck\"\nCHANNEL_NAME=\"Gabriel R\u00fceck\"\nCHANNEL_LINK=\"http:\/\/caipirinha.homelinux.org\/~gabriel\/\"\nDESCRIPTION=\"News from Gabriel R\u00fceck\"\nEDITOR=\"gabriel@caipirinha.homelinux.org (Gabriel R\u00fceck)\"\n#\n# Settings for the Image of the Website\n#\nIMG_URL=\"http:\/\/caipirinha.homelinux.org\/~gabriel\/Bilder\/Zeitung.jpg\"\n#\n# Settings for the Path File (containing all paths that shall be searched and their respective HTML links)\nPATH_FILE=\"\/home\/gabriel\/rss\/paths.txt\"\n#\n# Miscellaneous Settings\n#\n# Duration sets the number of days for the \"find\" command. Files which were modified up to $DURATION days, will be\n# taken into account.\n#\nDURATION=30<\/pre>\n\n\n\n<p>Wichtig ist bei eigenen Konfigurationsdateien nur, dass die \nentsprechenden Schl\u00fcsselworte genau so geschrieben werden wie in der \nallgemeinen Konfigurationsdatei <strong>\/etc\/rss\/rss.conf<\/strong>. Abgesehen von \neiner eigenen Konfigurationsdatei kann man aber auch dediziert eigene \nOptionen beim Aufruf des Skripts angeben. Folgende Optionen sind \nm\u00f6glich:\n<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>-D <em>Beschreibung<\/em><\/strong> definiert die Beschreibung des RSS-Feeds.<\/li><li><strong>-o <em>Dateiname<\/em><\/strong> gibt an, wo sich die zu verwendende Konfigurationsdatei befindet. Der Default-Wert ist <strong>\/etc\/rss\/rss.conf<\/strong>.<\/li><li><strong>-p <em>Dateiname<\/em><\/strong> gibt an, wo sich die Pfaddatei befindet, in welcher die zu durchsuchenden Verzeichnisse angegeben sind (siehe unten).<\/li><li><strong>-t <em>Zeitdauer<\/em><\/strong> gibt an, wieviele Tage die zu ber\u00fccksichtigenden Dateien (die in den RSS-Feed aufgenommen werden), alt sein d\u00fcrfen.<\/li><li><strong>-T <em>Titel<\/em><\/strong> definiert den Titel des RSS-Feeds.<\/li><\/ul>\n\n\n\n<p> Die dediziert angegebenen Optionen haben Vorrang gegen\u00fcber den Optionen in einer angegebenen Konfigurationsdatei. Eine mit <strong>-o<\/strong> angebene Konfigurationsdatei hat wiederum Vorrang gegen\u00fcber der allgemeinen Konfigurationsdatei <strong>\/etc\/rss\/rss.conf<\/strong>. <\/p>\n\n\n\n<p>Als letzte Datei in diesem Sammelsurium wird noch die \n\u00fcblicherweise in der Konfigurationsdatei referenzierte Pfaddatei \nben\u00f6tigt. Ein Beispiel einer Pfaddatei ist hier gezeigt:\n<\/p>\n\n\n\n<p><strong>\/home\/public\/paths.txt<\/strong>:\n<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># Path List for the RSS Script\n#\n# This file contains the folders that will be scanned by the RSS script.\n# Each line contains three elements which have to be separated by a | character. The structure is:\n#\n# path_to_be_scanned | HTML_prefix | Title | Optional path which is to be omitted\n#\n# It is important that the HTML_prefix does not have a trailing \/ character.\n#\n\/home\/public\/B\u00fccher|https:\/\/caipirinha.homelinux.org\/MM\/B\u00fccher|Books\n\/home\/public\/Dokumente|https:\/\/caipirinha.homelinux.org\/MM\/Dokumente|Documents\n\/home\/public\/Unterhaltung|https:\/\/caipirinha.homelinux.org\/MM\/Unterhaltung|Entertainment\n\/home\/public\/Spiele|https:\/\/caipirinha.homelinux.org\/MM\/Spiele|Games\n\/home\/public\/Linux|https:\/\/caipirinha.homelinux.org\/MM\/Linux|Linux\n\/home\/public\/Video|https:\/\/caipirinha.homelinux.org\/MM\/Filme|Movies\n#\/home\/public\/Video|https:\/\/caipirinha.homelinux.org\/MM\/Filme|Movies|.\/[[:digit:]]-*\n#\/home\/public\/Audio|https:\/\/caipirinha.homelinux.org\/MM\/Musik|Music\n\/home\/public\/Bilder|https:\/\/caipirinha.homelinux.org\/MM\/Fotos|Pictures\n\/home\/public\/Software|https:\/\/caipirinha.homelinux.org\/MM\/Software|Windows<\/pre>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"http:\/\/localhost\/mediawiki\/index.php\/Datei:RSS-Feed_in_Akregator.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"819\" src=\"https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/RSS-Feed_in_Akregator-1024x819.png\" alt=\"Akregator View\" class=\"wp-image-121\" srcset=\"https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/RSS-Feed_in_Akregator-1024x819.png 1024w, https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/RSS-Feed_in_Akregator-300x240.png 300w, https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/RSS-Feed_in_Akregator-768x614.png 768w, https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/RSS-Feed_in_Akregator.png 1280w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Akregator View<\/figcaption><\/figure>\n\n\n\n<p>Wegen des Bash-Skriptes sind hier leider einige Eigenarten zu beachten:\n<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Jede g\u00fcltige Zeile besteht aus drei Teilen: dem zu \ndurchsuchenden Pfad ohne &#8220;\/&#8221; am Ende, dem HTML-Link, unter dem dieses \nVerzeichnis zu finden ist und der Beschreibung, welche diesem \nVerzeichnis zuzuordnen ist<\/li><li>Die letzte Zeile muss mit einem Zeilenendekennzeichen abgeschlossen \nwerden, d.h. der Cursor muss beim Speichern in der letzten und leeren \nZeile sein.<\/li><\/ul>\n\n\n\n<p>Bei der Konfiguration des <a href=\"http:\/\/localhost\/mediawiki\/index.php\/Apache\">Apache<\/a>-Servers muss nat\u00fcrlich ber\u00fccksichtigt werden, dass die einzelnen Verzeichnisse wie beispielsweise <strong>\/home\/public\/B\u00fccher<\/strong> dann auch \u00fcber HTML unter <strong><a href=\"https:\/\/caipirinha.homelinux.org\/MM\/B\u00fccher\">https:\/\/caipirinha.homelinux.org\/MM\/B\u00fccher<\/a><\/strong> zug\u00e4nglich sind. Damit keine unbefugten Zugriffe stattfinden, empfehlen sich Zugangsbeschr\u00e4nkungen f\u00fcr den HTML-Zugriff.\n<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"http:\/\/localhost\/mediawiki\/index.php\/Datei:RSS-Feed_in_Firefox.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"960\" src=\"https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/RSS-Feed_in_Firefox-1024x960.png\" alt=\"Firefox View\" class=\"wp-image-123\" srcset=\"https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/RSS-Feed_in_Firefox-1024x960.png 1024w, https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/RSS-Feed_in_Firefox-300x281.png 300w, https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/RSS-Feed_in_Firefox-768x720.png 768w, https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/RSS-Feed_in_Firefox.png 1050w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Firefox View<\/figcaption><\/figure>\n\n\n\n<p>Au\u00dferdem m\u00fcssen die KDE-eigenen Piktogramme unter <strong>\/opt\/kde3\/share\/icons\/crystalsvg\/48&#215;48\/mimetypes<\/strong> unter dem Link <strong><a href=\"http:\/\/caipirinha.homelinux.org\/kde-icons\">http:\/\/caipirinha.homelinux.org\/kde-icons<\/a><\/strong>\n zug\u00e4nglich gemacht werden, denn das Skript bezieht sich auf dieses \nVerzeichnis, um Bilder in den RSS-Feed einzuf\u00fcgen. Allerdings wird das \nAuflisten der Piktogramme in diesem Webverzeichnis untersagt; es wird \nlediglich das Anzeigen eines dedizierten Piktogrammes gestattet, wenn \nman den vollen Dateinamen eingibt.\n<\/p>\n\n\n\n<p>Das hier abgebildete Skript <strong>update_rss.sh<\/strong> funktioniert \nalso nur dann richtig, wenn die zwei genannten sed-Skripte sowie \nmindestens eine g\u00fcltige Konfigurationsdatei korrekt installiert sind. \nWurde alles korrekt eingerichtet, dann kann man mit\n<\/p>\n\n\n\n<p><code>.\/update_rss.sh \/home\/public\/rss_index.xml<\/code>\n<\/p>\n\n\n\n<p>einen neuen RSS-Feed unter <strong>\/home\/public\/rss_index.xml<\/strong> \nerzeugen lassen. Man kann \u00fcbrigens anstatt einer Zieldatei f\u00fcr den \nRSS-Feed auch gleich mehrere Zieldateien angeben. Dann werden gleich \nmehrere identische Feeds in unterschiedlichen Verzeichnissen generiert.\n<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"http:\/\/localhost\/mediawiki\/index.php\/Datei:RSS-Feed_in_IE7.png\"><img loading=\"lazy\" decoding=\"async\" width=\"893\" height=\"734\" src=\"https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/RSS-Feed_in_IE7.png\" alt=\"Internet Explorer View\" class=\"wp-image-124\" srcset=\"https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/RSS-Feed_in_IE7.png 893w, https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/RSS-Feed_in_IE7-300x247.png 300w, https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/RSS-Feed_in_IE7-768x631.png 768w\" sizes=\"auto, (max-width: 893px) 100vw, 893px\" \/><\/a><figcaption>Internet Explorer View<\/figcaption><\/figure>\n\n\n\n<p>Der Aufruf\n<\/p>\n\n\n\n<p><code>.\/update_rss.sh -o $HOME\/rss\/rss.conf \/home\/public\/rss_index.xml<\/code>\n<\/p>\n\n\n\n<p>liest noch die Konfigurationsdatei <strong>$HOME\/rss\/rss.conf<\/strong>, wertet diese aus und erzeugt dann den RSS-Feed <strong>\/home\/public\/rss_index.xml<\/strong>.\n<\/p>\n\n\n\n<p>Ich will nicht verschweigen, dass der erzeugte RSS-Feed nicht \nimmer die RSS-Spezifikationen erf\u00fcllt. Dies h\u00e4ngt meist mit \nirgendwelchen Sonderzeichen im Dateinamen zusammen. Allerdings l\u00e4sst \nsich der Feed in den meisten Browsern oder Mail-Clients ohne Probleme \neinbinden.\n<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Doppelte Dateien l\u00f6schen<\/h2>\n\n\n\n<p>In den Benutzerverzeichnissen auf dem Server tummeln sich oft \nDateien, welche bereits in \u00f6ffentlichen Ordnern des Servers existieren. \nDadurch wird die gleiche Datei mehrfach auf dem Server abgelegt. Ein \nklarer Fall von Platzverschwendung. Das soll sich mit dem folgenden \nSkript \u00e4ndern:\n<\/p>\n\n\n\n<p><strong>kill_doubles.sh<\/strong>:\n<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/bin\/bash\n#\n# This script performs the following steps:\n#      1. Scan dedicated public folders and create MD5 hashes of all non-hidden files.\n#      2. Save a list of these files with MD5 hashes.\n#      3. Scan user folders and create MD5 hashes of all non-hidden files.\n#      4. Compare these MD5 hashes with the ones in the public folders.\n#      5. If a double file is detected, de\u00f6ete the public file in the personal folder and replace it with a link\n#         to the respective file in the public folder.\n#\n# Gabriel R\u00fceck, gabriel@caipirinha.homelinux.org, 10.09.2008\n#                last update:                      11.12.2011\n#\n\n# Pre-define some variables and read the configuration files.\nreadonly CHANGED_FILES='\/tmp\/changed_files.txt'\nreadonly CHECKSUM_FILE='\/home\/public\/Pr\u00fcfsummen.txt'\nreadonly GROUP='users'\nreadonly MAIL_RCPT='root@caipirinha'\nreadonly MAIL_SUBJ='Ge\u00e4nderte Benutzer-Dateien'\n# Do not bother with small files.\nreadonly SIZE='+30k'\n\numask 022\n# Scan dedicated public folders, create files with MD5 hashes in these folders and save the name of those files in another file named $CHECKSUM_LOCATIONS.\nrm ${CHECKSUM_FILE} 2&gt;\/dev\/null\nfor SCANPATH in \/home\/public\/Audio \/home\/public\/Bilder; do\n    find ${SCANPATH} -type f -size ${SIZE} -name \"[[:alnum:]]*\" -and -not -name \"Thumbs.db*\" -exec md5sum {} 2&gt;\/dev\/null \\; &gt;&gt; ${CHECKSUM_FILE}\ndone;\n\n# Browse through all MD5 hashes listed in $CHECKSUM_FILE.\nrm ${CHANGED_FILES} 2&gt;\/dev\/null\n# Browse through various folders\n# Observe the [ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6\u00dc] which is NOT equivalent to [A-Z\u00c4\u00d6\u00dc] under the locale de_DE.UTF-8, but only under the locale C.\nfor SCANPATH in \/home\/gabriel\/[ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6\u00dc]* \\\n                \/home\/joselia\/[ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6\u00dc]*; do\n    # Extract user name.\n    USER=$(echo ${SCANPATH} | sed -n 's\/^\\\/home\\\/\\([^\\\/]*\\).*\/\\1\/p')\n    # Find all normal files starting with an alphanumeric name (skip .files).\n    find \"${SCANPATH}\" -not -path '*\/.*' -type f -size ${SIZE} -exec md5sum {} 2&gt;\/dev\/null \\; |\n    (while read -r DATASET\n     do CHKSUM=$(echo \"${DATASET}\" | cut -c-32)\n        FILEPATH_IN_CHECK=$(echo \"${DATASET}\" | cut -c35-)\n        # Look for the first occurency of an identical checksum in $CHECKSUM_FILE.\n        RESULT=$(fgrep -m1 \"${CHKSUM}\" \"${CHECKSUM_FILE}\")\n        if [ -n \"${RESULT}\" ]; then\n           FILEPATH_REPLACE=$(echo \"$RESULT\" | cut -c35-)\n           # Check if the file that shall be linked to has a generic digikam file name. Those names are like:\n           # IMG_0000.JPG or P0000000.JPG\n           FNAME_IN_CHECK=${FILEPATH_IN_CHECK##*\/}\n           PNAME_REPLACE=${FILEPATH_REPLACE%\/*}\"\/\"\n           FNAME_REPLACE=${FILEPATH_REPLACE##*\/}\n           if [[ \"${FNAME_REPLACE}\" =~ ^[PI].*[0-9]\\.JPG$ ]] &amp;&amp; [ \"${FNAME_IN_CHECK}\"&nbsp;!= \"${FNAME_REPLACE}\" ]; then\n              # Replace the generic digikam name by the file name of the respective user file.\n              echo \"Umbenennung: ${FILEPATH_REPLACE}  \u2192  ${PNAME_REPLACE}${FNAME_IN_CHECK}\" &gt;&gt; ${CHANGED_FILES}\n              mv \"${FILEPATH_REPLACE}\" \"${PNAME_REPLACE}${FNAME_IN_CHECK}\"\n              # Update the variable $FILEPATH_REPLACE as the reference file has been renamed.\n              FILEPATH_REPLACE=${PNAME_REPLACE}${FNAME_IN_CHECK}\n           fi\n           # Write result into a tmp file.\n           echo \"Link: ${FILEPATH_IN_CHECK}  \u2192  ${FILEPATH_REPLACE}\" &gt;&gt; ${CHANGED_FILES}\n           # Replace the examined file by a link to the existing file.\n           rm \"${FILEPATH_IN_CHECK}\"\n           ln -s \"${FILEPATH_REPLACE}\" \"${FILEPATH_IN_CHECK}\"\n           chown -h ${USER}:${GROUP} \"${FILEPATH_IN_CHECK}\"\n        fi\n     done)\ndone\n\n# Send an email to $MAIL_RCPT if files have been replaced.\nif [ -s \"${CHANGED_FILES}\" ]; then\n   cat ${CHANGED_FILES} | mail -s \"${MAIL_SUBJ}\" \"${MAIL_RCPT}\"\nfi<\/pre>\n\n\n\n<p>In diesem Skript werden zun\u00e4chst alle Dateien in den \u00f6ffentlichen Verzeichnissen <strong>\/home\/public\/Audio<\/strong> und <strong>\/home\/public\/Bilder<\/strong> erfasst. F\u00fcr jede Datei wird die MD5-Pr\u00fcfsumme berechnet und in <strong>\/home\/public\/Pr\u00fcfsummen.txt<\/strong> abgelegt.\n<\/p>\n\n\n\n<p>Dann werden zwei Benutzerverzeichnisse durchsucht, und f\u00fcr die \ndort gefundenen Dateien, welche gr\u00f6\u00dfer als eine bestimmte, im Skript \nfestgelegte Mindestgr\u00f6\u00dfe sind, wird ebenfalls die MD5-Pr\u00fcfsumme \nberechnet. Das Skript vergleicht nun, ob eine solche Pr\u00fcfsumme schon in \nder Datei <strong>\/home\/public\/Pr\u00fcfsummen.txt<\/strong> existiert. Wenn dem so ist,\n dann bedeutet dies, dass die gerade bearbeitete Datei schon auf dem \nServer existiert. In diesem Fall l\u00f6scht das Skript die entsprechende \nDatei im Benutzerverzeichnis und ersetzt sie durch einen Link auf die \njeweilige Datei in <strong>\/home\/public\/Audio<\/strong> oder <strong>\/home\/public\/Bilder<\/strong>.\n Da es sich bei den meisten mehrfach vorkommenden Dateien um Fotos \nhandelt, pr\u00fcft das Skript aber noch behelfsm\u00e4\u00dfig, ob die bereits \nexistierende Datei einen generischen Namen hat, wie er von \nDigitalkameras kommt, also beispielsweise &#8220;P1234567.JPG&#8221; oder so. Diese \nPr\u00fcfung ist im hier abgedruckten Skript aber nicht vollkommen, sondern \nwird nur n\u00e4herungsweise durchgef\u00fchrt. Wenn also die bereits existierende\n Datei in <strong>\/home\/public\/Audio<\/strong> oder <strong>\/home\/public\/Bilder<\/strong> \neinen solchen generischen Namen tr\u00e4gt, im Benutzerverzeichnis aber schon\n umbenannt worden ist (z.B. weil der jeweilige Benutzer nun einen \n&#8220;richtigen&#8221; Namen vergeben hat), dann wird dieser Dateiname auch f\u00fcr die\n jeweilige Datei auf <strong>\/home\/public\/Audio<\/strong> oder <strong>\/home\/public\/Bilder<\/strong> \u00fcbernommen, damit auch andere Benutzer wissen, worum es sich bei dem entsprechenden Foto handelt.\n<\/p>\n\n\n\n<p>Zum Schluss verschickt das Skript dann noch eine Email, in der \u00fcber die ersetzten und umbenannten Dateien berichtet wird.\n<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Bluetooth-Infobox<\/h2>\n\n\n\n<p>Die Bluetooth-Infobox ist ein Skript, welches \u00fcber einen Eintrag in \nder crontab die Umgebung nach Ger\u00e4ten mit Bluetooth scannt und dann \nversucht, Dateien \u00fcber das OBEX Push-Protokoll an die gefundenen Ger\u00e4te \nzu verschicken. Damit kann man eine Art Informations-Box aufbauen, die \nDateien automatisch an Mobiltelefone in der n\u00e4heren Umgebung verschickt.\n Auf einer Messe ist mir das selbst einmal passiert.\n<\/p>\n\n\n\n<p>Dazu muss der Server nat\u00fcrlich mit einem USB-Dongle versehen \nwerden. Auf meiner Maschine habe ich einen USB-Bluetooth-Adapter der \nKlasse 1 von DELOCK (DELOCK 61477) eingesetzt, mit dem ich gute \nErfahrungen gemacht habe.\n<\/p>\n\n\n\n<p>Weiterhin m\u00fcssen \u00fcber YaST folgende Software-Pakete installiert werden:\n<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>bluez-libs<\/li><li>bluez-utils<\/li><li>libusb-devel<\/li><li>openobex-devel<\/li><li>yast2-bluetooth<\/li><\/ul>\n\n\n\n<p>Ferner muss noch das Programm <strong>ussp-push<\/strong> von Davide Libenzi compiliert und installiert werden. Die Beschreibung des Programmes und den Link zum Download gibt es auf <a href=\"http:\/\/www.xmailserver.org\/ussp-push.html\">[3]<\/a>. Mit <strong>ussp-push<\/strong> kann man Dateien \u00fcber das <strong>Object Push<\/strong>-Protokoll <a href=\"http:\/\/en.wikipedia.org\/wiki\/OBEX\">[4]<\/a>\n verschicken. Wenn man sich das Paket von Davide Libenzis Seite \nherunterl\u00e4dt, muss man es nur noch entpacken und dann das Programm \nentsprechend der dem tar-Archiv beigef\u00fcgten Anleitung compilieren. Dann \nsollte man das daraus entstandene Programm an eine zentrale Stelle \nkopieren, beispielsweise an <strong><code>\/usr\/sbin\/ussp-push<\/code><\/strong>.\n<\/p>\n\n\n\n<p>Jetzt schafft man sich in einem f\u00fcr alle zug\u00e4nglichen Pfad ein neues Verzeichnis, beispielsweise:\n<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">drwxr-sr-x 4 nobody users 128 25. Sep 18:00 \/home\/public\/Bluetooth-Infobox<\/pre>\n\n\n\n<p>Ich habe dieses Verzeichnis dem Benutzer <strong>nobody<\/strong> zugeordnet, \nweil das unten abgebildete Skript aus Sicherheitsgr\u00fcnden ebenfalls unter\n diesem Benutzer l\u00e4uft. In disem Verzeichnis wird das Skript auch die \nLog-Dateien anlegen, welche die Ausgaben des <strong>ussp-push<\/strong>-Kommandos \nprotokolliert. In diesem Verzeichnis m\u00fcssen nun zwei Unterverzeichnisse \nmit entsprechenden Rechten angelegt werden, und zwar:\n<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">drwxr-sr-x 2 nobody users 128 26. Sep 21:13 \/home\/public\/Bluetooth-Infobox\/database\ndrwxrwsr-x 2 nobody users  80 25. Sep 15:38 \/home\/public\/Bluetooth-Infobox\/outbox<\/pre>\n\n\n\n<p>Im Unterverzeichnis <code>outbox<\/code> k\u00f6nnen alle Benutzer der \nMaschine beliebige Dateien ablegen, die dann an die Mobiltelefone \nverschickt werden sollen, wenn das Skript abgearbeitet wird.\nIm Unterverzeichnis <code>database<\/code> wird das Skript sp\u00e4ter eine \nArt Datenbank anlegen, in welcher f\u00fcr jedes Mobiltelefon, an das \nmindestens eine Datei erfolgreich verschickt worden ist, eine Datei \nexistiert, welche die Unix-Zeitstempel und den Namen der verschickten \nDatei enth\u00e4lt.\n<\/p>\n\n\n\n<p>Mit diesen Vorbereitungen kann man nun das eigentliche Skript <strong>bt_infobox.sh<\/strong> \u00fcber einen Eintrag in der crontab von nobody aktivieren:\n<\/p>\n\n\n\n<p><strong>bt_infobox.sh<\/strong>:\n<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/bin\/bash\n#\n# Bluetooth Info Box\n#\n# This script searches for Bluetooth-enabled mobile phones in the proximity, registers their hardware address\n# and looks whether there are any new files in the outbox that have not yet been sent to these mobile phones.\n# It then sends the missing files to the mobile phones.\n#\n# Gabriel R\u00fceck, gabriel@caipirinha.homelinux.org, 25.09.2008\n#\n\n# Pre-define some variables and read the configuration files.\nreadonly WORKDIR='\/home\/public\/Bluetooth-Infobox'\n\n# Set the PATH variable and include \/usr\/sbin (where ussp-push has been put).\nPATH='\/usr\/sbin:\/usr\/bin:\/bin'\n\n# Scan for Bluetooth-enabled phones in the proximity and extract their machine address.\n# Check if a database file exists for the respective HW address.\n#   If that is the case, browse through all files in the outbox and see if they have already been sent to that phone.\n#      If they have not been sent to that phone, send them and write the file info into the database file.\n#   If no database file exists, send all files in the outbox to the phone and write the file info into the database file.\n# The database file contains the timestamp and the name of the files that have been sent from the outbox to the respective phone.\n\nhcitool scan | egrep -o '\\b[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}\\b' | \\\n        while read HW_ADDRESS\n        do if [ -f \"${WORKDIR}\/database\/${HW_ADDRESS}.txt\" ]\n           then\n             cd \"${WORKDIR}\/outbox\" &amp;&amp; find . -maxdepth 1 -type f -print 2&gt;\/dev\/null |\n                while read LOCAL_FNAME\n                do LONG_FNAME=$(stat -c '%Y&nbsp;%n' \"${LOCAL_FNAME}\")\n                   if (! fgrep -q \"${LONG_FNAME}\" \"${WORKDIR}\/database\/${HW_ADDRESS}.txt\")\n                   then REMOTE_FNAME=$(basename \"${LOCAL_FNAME}\")\n                        ussp-push \"${HW_ADDRESS}@\" \"${LOCAL_FNAME}\" \"${REMOTE_FNAME}\" &gt;&gt; \"${WORKDIR}\/ussp-push.log\" 2&gt;&amp;1 &amp;&amp; (echo \"${LONG_FNAME}\" &gt;&gt; \"${WORKDIR}\/database\/${HW_ADDRESS}.txt\"; sleep 3s)\n                   fi\n                done\n           else\n             cd \"${WORKDIR}\/outbox\" &amp;&amp; find . -maxdepth 1 -type f -print 2&gt;\/dev\/null |\n                while read LOCAL_FNAME\n                do REMOTE_FNAME=$(basename \"${LOCAL_FNAME}\")\n                   ussp-push \"${HW_ADDRESS}@\" \"${LOCAL_FNAME}\" \"${REMOTE_FNAME}\" &gt;&gt; \"${WORKDIR}\/ussp-push.log\" 2&gt;&amp;1 &amp;&amp; (stat -c '%Y&nbsp;%n' \"${LOCAL_FNAME}\" &gt;&gt; \"${WORKDIR}\/database\/${HW_ADDRESS}.txt\"; sleep 3s)\n                done\n           fi\n        done;<\/pre>\n\n\n\n<p>Der zugeh\u00f6rige Eintrag in der <strong>crontab<\/strong> lautet dann beispielsweise:\n<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># Crontab f\u00fcr nobody\n#\nLANG=de_DE.UTF-8\nLC_ALL=de_DE.UTF-8\nMAILTO=root\nSHELL=\/bin\/bash\n#\n 0 10-23 *  *  *        \/home\/gabriel\/bin\/bt_infobox.sh<\/pre>\n\n\n\n<p>Damit wird dieses Skript dann t\u00e4glich von 10:00-23:00 Uhr alle Stunde\n ausgef\u00fchrt. Wenn man eine Infobox realisieren will, an der sich die \nLeute nicht lange aufhalten, wie auf einer Messe, dann sollte man dieses\n Skript nat\u00fcrlich \u00f6fter ausf\u00fchren lassen.\n<\/p>\n\n\n\n<p>Wie funktioniert dieses Skript?\n<\/p>\n\n\n\n<p>Beim Ausf\u00fchren wird mit dem Kommando <code>hcitool scan<\/code> \nnach Bluetooth-f\u00e4higen Ger\u00e4ten gefahndet. Dann wird f\u00fcr jedes gefundene \nGer\u00e4t eine Schleife durchlaufen. In diesem Schleife pr\u00fcft das Skript \nzun\u00e4chst, ob f\u00fcr dieses Ger\u00e4t bereits einmal eine Datei verschickt \nworden ist. Dazu pr\u00fcft es, ob im Unterverzeichnis <code>database<\/code> \neine Datei mit dem Namen der Bluetooth-Netzwerkadresse existiert. Ist \ndies der Fall, dann wird eine weitere Schleife gestartet, welche alle \nDateien im Unterverzeichnis <code>outbox<\/code> durchl\u00e4uft und pr\u00fcft, ob\n eine Datei unter dem jeweiligen Namen und mit dem jeweiligen \nUnix-Zeitstempel schon einmal verschickt worden ist. Ist dies nicht der \nFall, dann wird versucht, diese Datei zu verschicken und bei Erfolg ein \nEintrag in der Datenbank gemacht. Die Ber\u00fccksichtigung des \nUnix-Zeitstempels erm\u00f6glicht es, eine Datei ohne \u00c4nderung ihres \nDateinamens immer wieder in der <code>outbox<\/code> zu aktualisieren. \nSie wird vom Skript dann als neu erkannt. So etwas macht Sinn f\u00fcr zu \nverschickende Dateien, die immer wieder unter dem gleichen Namen einen \nneuen Inhalt bekommen, eventuell durch ein anderes Skript.\n<\/p>\n\n\n\n<p>Ist ein neues Bluetooth-f\u00e4higes Ger\u00e4t erkannt worden, an das noch\n nie Dateien verschickt worden ist, dann wird ebenfalls eine Schleife \ndurchlaufen, welche alle Dateien im Unterverzeichnis <code>outbox<\/code> abarbeitet, diese an das entsprechende Ger\u00e4t verschickt und dann in die Datenbank schreibt.\n<\/p>\n\n\n\n<p>Die Schleife mit dem Befehl <code>sleep 3s<\/code> versucht \nsicherzustellen, dass beim Versand vieler kleiner Dateien keine Datei \nbeim Versand &#8220;verschluckt&#8221; wird. Das Skript durchsucht nur eine Ebene im\n Unterverzeichnis <code>outbox<\/code>. Es d\u00fcrfen daher dort keine Unterverzeichnisse angelegt werden.\n<\/p>\n\n\n\n<p>Hier ist ein Beispiel f\u00fcr Eintr\u00e4ge in der Datenbank, also f\u00fcr Dateien im Unterverzeichnis <code>database<\/code>:\n<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">-rw-r--r-- 1 nobody users 25 26. Sep 21:13 \/home\/public\/Bluetooth-Infobox\/database\/00:16:B8:13:1D:64.txt\n-rw-r--r-- 1 nobody users 25 25. Sep 18:00 \/home\/public\/Bluetooth-Infobox\/database\/00:1E:45:0F:96:32.txt<\/pre>\n\n\n\n<p>In einer solchen Datei befinden sich dann Eintr\u00e4ge wie:\n<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">1166212980 .\/Gabriel.jpg<\/pre>\n\n\n\n<p>Das zeigt, dass eine Datei namens <code>Gabriel.jpg<\/code> verschickt\n worden ist. Die Zahl am Anfang ist der Unix-Zeitstempel. Da es sich bei\n der Datenbank um Textdateien handelt, wird auf dem Server nicht viel \nSpeicherplatz verbraucht.\n<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Gr\u00f6\u00dfe eines Mailordners<\/h2>\n\n\n\n<p>Dieses einfache und nicht optimierte Skript bestimmt die Postfachgr\u00f6\u00dfe eines Benutzers im Ordner <strong>\/home\/public\/Mail\/<\/strong> auf dem Caipirinha-Server. Es wird im Rahmen einer <a href=\"http:\/\/localhost\/mediawiki\/index.php\/SNMP\">snmp<\/a>-Abfrage zur Postfachgr\u00f6\u00dfe benutzt und so aufgerufen:\n<\/p>\n\n\n\n<p><code>mailsize.sh  Benutzer<\/code>\n<\/p>\n\n\n\n<p><strong>mailsize.sh<\/strong>:\n<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/bin\/bash\n# Dieses Skript bestimmt die Gr\u00f6\u00dfe eines Benutzer-Mailordners.\n# Der Benutzername muss als Argument \u00fcbergeben werden.\n# Gabriel R\u00fceck, 07.01.2010\n\nreadonly MAILFOLDER='\/home\/public\/Mail\/'\n\n# Pr\u00fcfe auf das Vorhandensein eines g\u00fcltigen Arguments.\n# Wurde kein Argument geliefert, beende mit Fehlercode=1.\n# Wurde kein g\u00fcltiges Argument geliefert, beende mit Fehlercode=2.\nif [ $# -lt 1 ]; then\n   exit 1\nelif [&nbsp;! -d $MAILFOLDER$1 ]; then\n   exit 2\nelse\n   du -b --max-depth=0 $MAILFOLDER$1 | cut -f1\n   exit 0\nfi<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Bandbreite zu entfernten Maschinen<\/h2>\n\n\n\n<p>Dieses einfache und nicht optimierte Skript ermittelt die Bandbreite einer TCP-Verbindung von <a href=\"http:\/\/caipirinha.homelinux.org\/\"><strong>caipirinha.homelinux.org<\/strong><\/a> zu den Maschinen <a href=\"http:\/\/caipiroska.homelinux.org\/\"><strong>caipiroska.homelinux.org<\/strong><\/a> und <a href=\"http:\/\/rueeck.name\/\"><strong>rueeck.name<\/strong><\/a>. Es wird ebenfalls im Rahmen einer <a href=\"http:\/\/localhost\/mediawiki\/index.php\/SNMP\">snmp<\/a>-Abfrage benutzt und so aufgerufen (hier mit <strong>rueeck.name<\/strong> als Beispiel-Argument):\n<\/p>\n\n\n\n<p><code>bandwidth.sh rueeck.name<\/code>\n<\/p>\n\n\n\n<p><strong>bandwidth.sh<\/strong>:\n<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/bin\/bash\n# Dieses Skript ermittelt die Bandbreite einer TCP-Verbindung zum Zielrechner.\n# Gabriel R\u00fceck, 07.07.2012\n\n# Pr\u00fcfe auf das Vorhandensein eines g\u00fcltigen Arguments.\n# Wurde kein Argument geliefert, beende mit Fehlercode=1.\nif [ $# -lt 1 ]; then\n   exit 1\nfi\n\n# Messe die Bandbreite und berechne den Wert in B\/s\nbps=$(iperf -f k -x CMSV -c ${1} | sed -n 's\/.*Bytes *\\([0-9.]\\{1,5\\} [KM]\\)bits.*\/\\1\/p')\nvalue=$(echo ${bps} | cut -f1 -d\" \")\ndecimal=$(echo ${bps} | cut -f2 -d\" \")\nif [ \"${decimal}\" = \"K\" ]; then\n   echo $(echo \"${value:=0}*125\" | bc)\nelif [ \"${decimal}\" = \"M\" ]; then\n   echo $(echo \"${value:=0}*125000\" | bc)\nfi<\/pre>\n\n\n\n<p>Auf den entfernten Maschinen muss dann ein <strong>iperf<\/strong>-Dienst \nlaufen. Momentan benutze ich dieses Skript aber nicht, weil der \niperf-Dienst auf meinen Maschinen h\u00e4ufig zu Problemen gef\u00fchrt hat.\n<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Ping-Zeiten zu entfernten Maschinen<\/h2>\n\n\n\n<p>Dieses einfache und nicht optimierte Skript ermittelt die Ping-Zeiten von <a href=\"http:\/\/caipirinha.homelinux.org\/\"><strong>caipirinha.homelinux.org<\/strong><\/a> zu 3 im Skript selbst definierten Maschinen, in diesem Fall <a href=\"http:\/\/caipiroska.homelinux.org\/\"><strong>caipiroska.homelinux.org<\/strong><\/a>, <a href=\"http:\/\/rueeck.name\/\"><strong>rueeck.name<\/strong><\/a>\n und zu ein kommerzieller VPN-Anbieter. Es kann die Ping-Zeiten auf den \noffenen und \u00fcber das VPN selbst ermitteln. Die gewonnenen Daten werden \nf\u00fcr <a href=\"http:\/\/localhost\/mediawiki\/index.php\/MRTG\">mrtg<\/a>-Grafiken benutzt. Das Skript wird so aufgerufen:\n<\/p>\n\n\n\n<p><code>pingtimes.sh gw0|gw1|gw2|tun0|tun1|tun2<\/code>\n<\/p>\n\n\n\n<p><strong>pingtimes.sh<\/strong>:\n<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/bin\/bash\n# Dieses speziell auf meine Anwendungszwecke abgestimmte Skript ermittelt die Pingzeiten zu meinen VPN-Gateways.\n# Gabriel R\u00fceck, 08.12.2012\n\n# Pr\u00fcfe auf das Vorhandensein eines g\u00fcltigen Arguments. Wurde kein Argument geliefert, beende mit Fehlercode=1.\nif [ $# -lt 1 ]; then\n   exit 1\nfi\n\nreadonly EVPNLOG='\/var\/log\/openvpn.log'\n\ncase \"$1\" in\n     gw0)  DEST='rueeck.name';;\n     tun0) DEST=$(ifconfig tun0 2&gt;\/dev\/null | sed -n 's\/.*inet addr:\\([0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.\\)[0-9]\\{1,3\\}.*\/\\1\/p')\"1\"\n             if [ \"${DEST}\" == \"1\" ]; then\n                exit 2\n             fi;;\n     gw1)  DEST='caipiroska.homelinux.org';;\n     tun1) DEST=$(ifconfig tun1 2&gt;\/dev\/null | sed -n 's\/.*inet addr:\\([0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.\\)[0-9]\\{1,3\\}.*\/\\1\/p')\"1\"\n             if [ \"${DEST}\" == \"1\" ]; then\n                exit 2\n             fi;;\n     gw2)  DEST=$(cat ${EVPNLOG} | sed -n 's\/.*Peer Connection Initiated with \\([0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\).*\/\\1\/p' | tail -n1);;\n     tun2) DEST=$(ifconfig tun2 2&gt;\/dev\/null | sed -n 's\/.*inet addr:\\([0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}\\.\\)[0-9]\\{1,3\\}\\.[0-9]\\{1,3\\}.*\/\\1\/p')\"0.1\"\n             if [ \"${DEST}\" == \"0.1\" ]; then\n                exit 2\n             fi;;\n     *)      exit 1;;\nesac\n\n# Bestimme die durchschnittliche Ping-Dauer in ms aus 2 Versuchen\nPINGTIME=$(ping -c2 -W3 ${DEST} | fgrep \"avg\" | cut -d\"\/\" -f5 | cut -d\".\" -f1)\nif [ -z \"${PINGTIME}\" ]; then\n   echo \"0\"\nelse\n   echo ${PINGTIME}\nfi<\/pre>\n\n\n\n<p>In diesem Skript ist <strong>\/var\/log\/openvpn.log<\/strong> die Log-Datei eines kommerziellen Anbieters. Diese Log-Datei muss nat\u00fcrlich auch in der Konfiguration von <a href=\"http:\/\/localhost\/mediawiki\/index.php?title=OpenVPN&amp;action=edit&amp;redlink=1\">openvpn<\/a>\n entsprechend konfiguriert werden. In der Log-Datei findet sich nach \neinem erfolgreichen Aufbau der VPN-Verbindung die IP-Adresse des \nVPN-Servers, und zwar in einer Zeile mit den Begriffen <strong>Peer Connection Initiated with<\/strong>.\n Das ist eine sinnvolle Sache, weil viele kommerzielle VPN-Anbieter \nmehrere Server zur Auswahl haben oder gar ein Load-Balancing machen, in \ndessen Rahmen ein FQDN auf verschiedene IPs aufgel\u00f6st werden kann. Der \nAutomatismus in diesem Skript macht daher Sinn.\n<\/p>\n\n\n\n<p>Wenn eine Verbindung blockiert wird, dann gibt es einen Timeout \noder eine Fehlermeldung beim Ping-Kommando, und die nachfolgende \nVerarbeitung mit dem <strong>sed<\/strong>-Kommando resultiert dann in einem leeren String. In diesem Fall gibt das Skript eine 0 zur\u00fcck. Somit sehe ich in der <a href=\"http:\/\/localhost\/mediawiki\/index.php\/MRTG\">mrtg<\/a>-Grafik\n direkt, dass es bei der entsprechenden Verbindung zu Problemen gekommen\n ist, weil sich dann eine (blaue) Nulllinie einstellt.\n<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">VPN-Datenvolumen ermitteln<\/h2>\n\n\n\n<p>Dieses einfache und nicht optimierte Skript ermittelt das aufgelaufene VPN-Datenvolumen von <a href=\"http:\/\/caipirinha.homelinux.org\/\"><strong>caipirinha.homelinux.org<\/strong><\/a> zu 3 entfernten Maschinen, zu denen eine <a href=\"http:\/\/localhost\/mediawiki\/index.php?title=OpenVPN&amp;action=edit&amp;redlink=1\">openvpn<\/a>-Verbindung besteht, in diesem Fall die Maschinen <a href=\"http:\/\/caipiroska.homelinux.org\/\"><strong>caipiroska.homelinux.org<\/strong><\/a>, <a href=\"http:\/\/rueeck.name\/\"><strong>rueeck.name<\/strong><\/a> und zu ein kommerzieller VPN-Anbieter. Das Skript wird ebenfalls im Rahmen einer <a href=\"http:\/\/localhost\/mediawiki\/index.php\/SNMP\">snmp<\/a>-Abfrage zur Darstellung einer <a href=\"http:\/\/localhost\/mediawiki\/index.php\/MRTG\">mrtg<\/a>-Grafik benutzt. Es wird so aufgerufen:\n<\/p>\n\n\n\n<p><code>vpn_traffic.sh tun0|tun1|tun2<\/code>\n<\/p>\n\n\n\n<p><strong>vpn_traffic.sh<\/strong>:\n<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/bin\/bash\n# Dieses speziell auf meine Anwendungszwecke abgestimmte Skript ermittelt Verkehrsdaten zu meinen VPN-Gateways.\n# Gabriel R\u00fceck, 05.12.2012\n\n# Pr\u00fcfe auf das Vorhandensein g\u00fcltiger Argumente. Wurden keine ausreichenden Argumente geliefert, beende mit Fehlercode=1.\nif [ $# -lt 2 ]; then\n   exit 1\nfi\n\nreadonly STATUSDIR='\/var\/run\/openvpn\/'\n\ncase \"$1\" in\n     tun0)  STATUSFILE='status-rueeck';;\n     tun1)  STATUSFILE='status-caipiroska';;\n     tun2)  STATUSFILE='status-Kommerzielles_VPN';;\n     *)     exit 2;;\nesac\n\ncase \"$2\" in\n     r|read)   SEARCHTERM='TCP\/UDP read bytes';;\n     w|write)  SEARCHTERM='TCP\/UDP write bytes';;\n     *)        exit 2;;\nesac\n\n# Lese den aufgelaufenen Datenverkehr aus der gew\u00e4hlten Variable aus\ncat ${STATUSDIR}${STATUSFILE} | fgrep \"${SEARCHTERM}\" | cut -d\",\" -f2<\/pre>\n\n\n\n<p><strong>Kommerzielles_VPN<\/strong> muss freilich durch den Hostnamen oder die \nIP-Adresse des VPN-Gateways eines kommerziellen Anbieters ersetzt \nwerden. Das Skript benutzt die min\u00fctlich aktualisierten Stati der <a href=\"http:\/\/localhost\/mediawiki\/index.php?title=OpenVPN&amp;action=edit&amp;redlink=1\">openvpn<\/a>-Verbindungen und nimmt weiterhin an, dass diese Verbindungen auch ihre Stati im Verzeichnis <strong>\/var\/run\/openvpn\/<\/strong> ablegen. Die <a href=\"http:\/\/localhost\/mediawiki\/index.php?title=OpenVPN&amp;action=edit&amp;redlink=1\">openvpn<\/a>-Verbindungen m\u00fcssen demnach auch entsprechend konfiguriert worden sein.\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Auf dieser Seite gibt es verschiedene Skripte, welche ich auf dem Caipirinha-Server einsetze, um anfallende Verwaltungsaufgaben zu l\u00f6sen. Diese Skripte sollen als Anregung zur Erstellung eigener Skripte dienen, k\u00f6nnen aber nat\u00fcrlich auch komplett \u00fcbernommen und bei Bedarf angepasst werden. <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[35],"tags":[74,75],"class_list":["post-94","post","type-post","status-publish","format-standard","hentry","category-it","tag-administration","tag-shell"],"_links":{"self":[{"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=\/wp\/v2\/posts\/94","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=94"}],"version-history":[{"count":2,"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=\/wp\/v2\/posts\/94\/revisions"}],"predecessor-version":[{"id":125,"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=\/wp\/v2\/posts\/94\/revisions\/125"}],"wp:attachment":[{"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=94"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=94"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=94"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}