Jul 13

Wenn in einem Ordner eine große Anzahl von Dateien liegt, verweigern cp, mv usw. ihren Dienst mit der Meldung:

$ mv *.png ../target/
bash: /bin/mv: Argument list too long

Abhilfe schafft find mit dem Parameter exec:

find . -name "*.png" -exec mv {} ../target/ \;

Der Nachteil der find-Methode mit dem Parameter exec ist, dass für jede Datei der Befehl in exec ausgeführt wird. Performanter ist hingegen xargs, das die übergebene Liste in kleinere Listen aufteilt, sodass diese dann von cp, mv, etc. noch verarbeitet werden können:

find . -name "*.png" | xargs -0 mv -t ../target/
Jun 16

Für (private) ADSL-Anschlüsse liefert die Telekom Austria das Thomson TG585 v7 aus. Wer nicht die DNS-Server des Providers verwenden möchte, sondern z.B. einen Filter zum Schutz vor Malware-Seiten oder eine Korrektur für Tippfehler in Domains haben möchte, kann die Nameserver von OpenDNS kostenlos verwenden. Diese Änderungen sind nur sinnvoll, wenn man nur einen Internetanschluss und kein aonTV hat, da letzteres sonst nicht mehr funktioniert. Um die DNS-Server zu konfigurieren verbindet man sich via Telnet mit dem Modem – hierfür tippt man in die Konsole/Eingabeaufforderung/Terminal den Befehl “telnet dsldevice” oder “telnet 10.0.0.138″. Daraufhin werden Benutzername und Passwort abgefragt – beide Felder lässt man leer. Als nächstes fügt man die OpenDNS-Nameserver mit den Befehlen “dns server route add dns=208.67.222.222 metric=0 intf=INTERNET” und “dns server route add dns=208.67.220.220 metric=0 intf=INTERNET” hinzu. Mit dem Befehl “dns server route list” kann man die aktuelle Nameserver-Konfiguration anzeigen lassen – auf diesem Modem:

DNS Server Entries:
  DNS Server     Source                Label              Metric Intf         State  Domain
S 208.67.222.222                                          0      INTERNET      UP      *
S 208.67.220.220                                          0      INTERNET      UP      *
D 10.156.0.33                                             10     MGMT          UP      *
D 10.156.0.49                                             10     MGMT          UP      *
D 194.48.139.254                                          30     INTERNET      UP      *
D 194.48.124.200                                          30     INTERNET      UP      *

Abschließend speichert man die Konfiguration mit dem Befehl “saveall” und beendet die Telnet-Sitzung mit “exit”. Ruft man nun die Seite http://www.opendns.com/welcome/ auf, wird die Meldung “Welcome to OpenDNS!” angezeigt, wenn die Konfiguration erfolgreich war. Weitere Konfigurationsanleitungen findet man in der Knowledge Base von OpenDNS.

Jan 15

Mac OS X verhindert das Ausführen von mehreren Instanzen eines Programms unter einem Benutzer. Bei Instant Messengern ist es allerdings häufig der Fall, dass man zumindest zwei Accounts/Konten (z.B. Privat und Firma) besitzt und mit diesen auch zur selben Zeit Online sein möchte. Skype verwendet leider ein proprietäres Protokoll und es ist somit nicht möglich Programme wie Adium für die Verbindung mit mehreren Konten einzusetzen, sondern man ist auf das Skype.app angewiesen. Skype selbst unterstützt auch nicht die Verwendung von mehreren Konten gleichzeitig. D.h. es bleibt nur die Möglichkeit zwei Instanzen von Skype laufen zu lassen, dafür muss man folgendes machen:

  1. Ein zweites Benutzerkonto (hier: “Privat”) für Mac OS X wird benötigt, d.h. dieses muss in den Systemeinstellungen anlegt sein bzw. werden
  2. Erste Skype-Instant wie gewohnt oder über das Terminal starten: “/Applications/Skype.app/Contens/MacOS/Skype”
  3. Benutzer im Terminal wechseln: “su Privat” (zuvor festgelegtes Passwort für den Benutzer muss eingegeben werden)
  4. Zweite Skype-Instanz über das Terminal starten: ”/Applications/Skype.app/Contens/MacOS/Skype”

Das lässt sich auch alles automatisieren, indem man sich ein kleines Shell-Skript schreibt. Damit das Passwort nicht immer eingegeben werden muss, kann auch die sudoers-Datei entsprechend bearbeitet werden – über eventuelle Sicherheitseinbußen sollte man sich im Klaren sein.

Oct 06

TYPO3 kennt seit Version 4.1 zwei verschiedene Wege, wie man einen Cronjob ausführen bzw. generell eine Aufgabe über das CLI (Command Line Interface) bzw. die Konsole starten kann. Ich werde hier der Vollständigkeit halber beide Wege aufzeigen und diese in “State-of-the-Art” und ”Old School” einteilen. Der Vorteil der neueren Methode ist, dass man sich um Pfade usw. nicht mehr kümmern muss, sondern alle Gemeinsamkeiten von TYPO3 bereitgestellt werden und somit die eigentliche Aufgabe, die Entwicklung des spezifischen Skripts, im Vordergrund bleibt.

State-of-the-Art

Für neu erstellte CLI-Skripte sollte stets dieser Weg eingeschlagen werden.

  1. Systemerweiterung “lowlevel” installieren (ist standardmäßig installiert)
  2. Erstellen eines BE-Benutzers beginnend mit “_cli_” (z.B. “_cli_cronjob” – Passwort spielt dabei keine Rolle)
  3. Erstellen eines Ordners namens “cli” im Ordner der Extension (z.B. in “typo3conf/ext/extensionkey/”)
  4. Erstellen einer Datei (z.B. “class.tx_extensionkey_cli.php” – Name grundsätzlich egal) im in Schritt 3 erstellten Ordner “cli” mit dem Inhalt [1]
  5. Erstellen (sofern noch nicht vorhanden) der Datei “ext_localconf.php” im in Schritt 3 erstellten Ordner “cli” im Ordner der Extension (z.B. in “typo3conf/ext/extensionkey/”) mit dem Inhalt [2] (vorhandenen Inhalt nicht überschreiben, sondern nur hinzufügen)
  6. Aufrufen des Skripts mit absolutem Pfad (z.B. “/var/www/typo3/cli_dispatch.phpsh extensionkey job”)
Hinweis: Sollte das Skript nicht ausgeführt werden, bitte überprüfen ob die Datei cli_dispatch.phpsh die erforderlichen Rechte (0755 bzw. rwxr-xr-x) aufweist.
[1]:
<?php
/***************************************************************
*  Copyright notice
*
*  (c) 2008 Your name <email@example.com>
*  All rights reserved
*
*  This script is part of the TYPO3 project. The TYPO3 project is
*  free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  The GNU General Public License can be found at
*  http://www.gnu.org/copyleft/gpl.html.
*
*  This script is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
if (!defined ('TYPO3_cliMode')) 	die ('Access denied: CLI only.');

require_once(PATH_t3lib.'class.t3lib_cli.php');

class tx_extensionkey_cli extends t3lib_cli {
	var $prefixId      = 'tx_extensionkey_cli';		// Same as class name
	var $scriptRelPath = 'cli/class.tx_extensionkey_cli.php';	// Path to this script relative to the extension dir.
	var $extKey        = 'extensionkey';	// The extension key.

	function tx_extensionkey_cli() {
		parent::t3lib_cli();

		$this->cli_options = array_merge($this->cli_options, array(
		));

		$this->cli_help = array_merge($this->cli_help, array(
			'name' => 'extensionkey CLI',
			'synopsis' => 'synopsis',
			'description' => 'description',
			'examples' => 'typo3/cli_dispatch.phpsh ' . $this->extKey . ' TASK',
			'author' => '(c) 2008 Your name <email@example.com>',
		));

		// read backend conf
		$this->conf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][$this->extKey]);
	}

	function cli_main($argv) {
		// disable output buffer
		ob_end_clean();

		// validate input
		$this->cli_validateArgs();

		// select called function
		switch ((string)$this->cli_args['_DEFAULT'][1]) {
			case 'job':
				$this->job();
				break;
			default:
				$this->cli_help();
				break;
		}
	}

	function job() {
		$this->cli_echo("Press keyn");
		$input = $this->cli_keyboardInput();
		$this->cli_echo('Your input: ' . $input . "n");
	}

}

$extensionkey = t3lib_div::makeInstance('tx_extensionkey_cli');
$extensionkey->cli_main($_SERVER['argv']);

?>
[2]:
<?php
  ## Setting up script that can be run through cli_dispatch.phpsh
if (TYPO3_MODE == 'BE') {
	$TYPO3_CONF_VARS['SC_OPTIONS']['GLOBAL']['cliKeys'][$_EXTKEY] = array('EXT:'.$_EXTKEY.'/cli/class.tx_extensionkey_cli.php','_CLI_cronjob');
}
?>
Old School
Für neu erstellte CLI-Skripte sollte stets der “State-of-the-Art”-Weg eingeschlagen werden.
  1. Analog zu “State-of-the-Art”
  2. Analog zu ”State-of-the-Art”
  3. Analog zu ”State-of-the-Art”
  4. Erstellen der Datei “conf.php” im in Schritt 3 erstellten Ordner “cli” mit dem Inhalt [3]
  5. Erstellen der Datei “cronjob.phpsh” im in Schritt 3 erstellten Ordner “cli” mit dem Inhalt [4]
  6. Aufrufen des Skripts mit absolutem Pfad (z.B. “/var/www/typo3conf/ext/extensionkey/cli/cronjob.phpsh”)
Hinweis: Sollte das Skript nicht ausgeführt werden, bitte überprüfen ob die Datei cronjob.phpsh die erforderlichen Rechte (0755 bzw. rwxr-xr-x) aufweist.
[3]:
<?php 
// DO NOT REMOVE OR CHANGE THESE 3 LINES: 
define('TYPO3_MOD_PATH', '../typo3conf/ext/extensionkey/cli/'); 
$BACK_PATH = '../../../../typo3/'; 
$MCONF['name'] = '_CLI_cronjob'; //use name of your BE-User 
?>
[4]:
#! /usr/bin/php -q 
<?php 

// ***************************************** 
// Standard initialization of a CLI module: 
// ***************************************** 

 // Defining circumstances for CLI mode: 
define('TYPO3_cliMode', TRUE); 

 // Defining PATH_thisScript here: Must be the ABSOLUTE path of this script 
in the right context: 
 // This will work as long as the script is called by it's absolute path! 
define('PATH_thisScript',$_ENV['_']?$_ENV['_']:$_SERVER['_']); 

 // Include configuration file: 
require(dirname(PATH_thisScript).'/conf.php'); 

 // Include init file: 
require(dirname(PATH_thisScript).'/'.$BACK_PATH.'init.php'); 

# YOUR CODE GOES HERE
?>
Die Diskussion zu “Old School” vs. “State-of-the-Art” der TYPO3 Dev-Mailinglist kann auf Nabble nachgelesen werden.
Jul 06

Wenn man ein Projekt in einem SVN-Repository abgelegt hat, werden lokal in jedem Ordner des Projekts .svn-Ordner angelegt, die Informationen für die SVN-Synchronisation beinhalten. Im Datei-Browser werden mit einem Punkt beginnende Dateien/Ordner (z.B. auch .bash_history,…), überlicherweise nicht angezeigt. In der Konsole bzw. im Terminal kann man diese Dateien/Ordner allerdings schnell löschen, wenn man dies möchte. Ist beispielsweise eine SVN-Synchronisation nicht mehr erforderlich und möchte man die .svn-Ordner rekursiv löschen, genügt folgender Befehl:

find . -type d -name .svn -exec rm -Rf {} \;

find . sucht nach allen Dateien/Ordnern rekursiv in dem Verzeichnis, in dem es aufgerufen wurde. Der Parameter -type d sorgt dafür, dass das Suchergebnis nur Ordner zurückliefert, mit -name wird der Ordnername auf .svn beschränkt. Anschließend wird noch die auszuführende Funktion mit -exec rm -Rf {} übergeben, nämlich rekursives löschen der gefundenen Ordner ohne weitere Benutzereingabe.