CRON als Root soll ODBC Abfragen machen, kennt jedoch die Zugangsdaten im Cron nicht

Hobbystern

Hobbystern

Wahl-Debianer
Hallo Gemeinde,

das ist ja mal ein Titel :-) Nun gut.

Schlicht und einfach, ich muss per Cron SQL Abfragen per ODBC fahren, dazu nutze ich hier FreeTDS und PHP, die Zugangsdaten für den Server liegen in der odbc.ini - nur von Root zu öffnen und zu lesen.

Mache ich es direkt als root ist alles okay.
Mache ich es per cron als root (crontab -e als root) bekomme ich Fehlermeldungen das der Server nicht bekannt wäre (php-mssql nennt es interessanter, aber der sinn stimmt)

Habe ich etwas vergessen - es geht hier um ca. 15 PHP Skripte die täglich Daten ziehen und verarbeiten, alle arbeiten an der Konsole einwandfrei, als CronUser "root" arbeiten alle nicht mehr.

Ich wäre sehr dankbar wenn Ihr mir helfen könntet!

LG Stefan
 
Morgen,

wie sehen die Aufrufe aus? Würde im ersten moment auf nicht passende Include-Pfade tippen.

mfg
HeadCrash
 
Keine schlechte Idee, ich würde Dir da sofort Recht geben - konkret gefunden hab ich leider noch nix :

exemplarischer Inhalt der crontab:
Code:
SHELL=/bin/sh
PATH=/usr/bin:/usr/sbin:/sbin:/bin
# Minute Stunde Tag(Monat) Monat  Tag(Woche)   Kommando
26      13      *       *       1-5     /etc/skripte/tagesumsatz.sh 1>/dev/null

Das Bash Skript ruft danach die php-cli auf :

Code:
php warengruppen-kontrolle.php

php liegt in /usr/bin (included oben)
Code:
/usr/bin/php
/usr/bin/php4
/usr/bin/php5
/usr/bin/php5-cgi
/usr/bin/php-cgi

Die einzigen Dateien die in Zusammenhang mit PHP und ODBC stehen habe ich per locate odbc | grep php hier gefunden :

Code:
/etc/php5/conf.d/odbc.ini
/etc/php5/conf.d/pdo_odbc.ini

Die odbc.ini sieht interessant aus und sollte meine Einstellungen beinhalten :

Code:
# configuration for php ODBC module
extension=odbc.so

Tut sie aber nicht - meine Einstellungen sind in /etc/odbc.ini und als symlink in /root/.odbc.ini

Code:
[ODBC Data Sources]
UBU = Weihnachtsmann

[Default]
Driver          =       FreeTDS

[UBU]
Driver          =       FreeTDS
Description     =       nix
Trace           =       no
TraceFile       =       /var/log/freesql.log
ForceTrace      =       no
ServerName      =       weihnachtsmann

Eine weitere (in Frage kommende) Konfigurationseinstellungen (wenn auch veraltet, da heute über php-mssql gelöst) findet sich in /etc/freetds/freetds.conf , ebenfalls als symlink in /root/.freetds.conf
Code:
[global]
        # TDS protocol version
        tds version = 8.0

        # Whether to write a TDSDUMP file for diagnostic purposes
        # (setting this to /tmp is insecure on a multi-user system)
        dump file append = /var/log/freetds.log
        debug flags = 0x08

        # Command and connection timeouts
        timeout = 30
        connect timeout = 30

        # If you get out-of-memory errors, it may mean that your client
        # is trying to allocate a huge buffer for a TEXT field.
        # Try setting 'text size' to a more reasonable limit
        ; text size = 64512

[UBU]
        host = 10.0.0.12
        port = 1433
        tds version = 8.0

Rufe ich das SH Skript manuell als root auf - OK, als Cron wird die Einstellungsdatei für den Zugriff nicht gefunden?!

Was habe ich da übersehen was er hat wenn ich mich manuell anmelde - aber nicht wenn er über cron reingeht (also die include zeile aus der crontab nutzt)?
 
Ups - irgendwie habe ich es geschafft über Dir zu antworten ?!
 
Keine schlechte Idee, ich würde Dir da sofort Recht geben - konkret gefunden hab ich leider noch nix :

Das Bash Skript ruft danach die php-cli auf :

Code:
php warengruppen-kontrolle.php

Den Aufruf würde ich persönlich mit einem absoluten Pfad absetzen.

Dachte auch eher an die Include-Pfade in php. Sprich die, in welcher include() und require() die odbc.ini suchen, ich meine die mit dem Passwort nicht die zum php-Modul.

Damit sollte sich die Variable include_path anpassen lassen.
Code:
  -d foo[=bar]     Define INI entry foo with value 'bar'

Code:
Var:                   Lokal:                                        Global:
## Default für Debian Lenny
# php -i | grep include_path
include_path => .:/usr/share/php:/usr/share/pear => .:/usr/share/php:/usr/share/pear

## geändert
#php -d include_path=".:/tmp/" -i | grep include_path
include_path => .:/tmp/ => .:/tmp/

mfg
HeadCrash
 
Zuletzt bearbeitet:
Hallo HeadCrash,

ich verstehe was Du meinst und ich weiss auch wie ich es umsetzen könnte - wenn ich nur wüsste wo die odbc included würde, wäre ich einen grossen Schritt weiter. Irgendwo muss ja definiert sein das Sie solange ich manuell eingeloggt bin sie included ist, per cron fehlt dieser Eintrag und wir müssen ihn manuell setzen...

Code:
asterisk:/etc# php -i | grep include_path
include_path => .:/usr/share/php:/usr/share/pear => .:/usr/share/php:/usr/share/pear
Ich habe mal in apache´s Konfig für das Modul php gesehen, Fehlanzeige, auch der string "odbc.ini" ist nicht im ganzen /etc/ Verzeichnis zu finden , genausowenig in /root/

Weisst Du wo included werden müsste, oder gehen wir einfach den "Option -d" Weg mit einem absoluten Pfad zu phpy..?

LG Stefan

Edit : Wieso setzt er mich wie wild west ein, wenn ich Dir antworte??

Edit 2 : ich habe mir es nun etwas einfacher gemacht - SymLink von /etc/odbc.ini -> /usr/share/php5
Neuer Symlink von /usr/share/php5 -> /usr/share/php (verz php existierte schlichtweg nicht :-?)

mal sehen
 
Zuletzt bearbeitet:
Hmm, grep -R "include\|require" auf deine PHP-Skripte ;) ?

Nur noch mal für mich zum verstehen, deine Verzeichnisstruktur stelle ich mir grade irgendwie so vor:
/foo/bar/odbc.ini
/foo/bar/warengruppen-kontrolle.php
/foo/bar/noch_mehr_php_skripte_die_alle_den_odbc_verwenden
Dann müßte irgendwo in der "/foo/bar/warengruppen-kontrolle.php" ein include(odbc.ini) oder require(odbc.ini) stehen.
Wenn du die Skripte per Kommandozeile startest befindest du dich wahrscheinlich auch im Verzeichnis "/foo/bar/" oder?

Poste doch mal bitte die Fehlermeldung die php erzeugt.
 
Verzeichnisstruktur sieht im konkreten Falle so aus :

Code:
/etc/odbc.ini
/etc/skripte (und unterverzeichnisse für spezielle - grössere Pakete)
Include´s habe ich nicht verwandt, da das gesamte Skript aus einem schlichten Aufruf besteht und maximal noch einer Variablenmanipulation :

Code:
<?php

$connect = odbc_connect("serverdefinition", "user", "pwd");
$query = "SELECT Artikelnummer, Suchname FROM Artikel WHERE Warengruppe <> Kassenspeicher ORDER BY Artikelnummer";
$ergebnis = odbc_exec($connect, $query);
while(odbc_fetch_row($ergebnis)) {
$field1 = odbc_result_all($ergebnis);   // Wir zeigen die gesamte Ausgabe des SELECTs
echo "$field1"."\n";
}
Ich habe gerade mal nach DIESER Anleitung die Installation/konfiguration eines sauberen PHP Moduls mit ODBC zugriff nachverfolgt (meine Installation kam aus dem Paketmanager von Debian) und habe phpinfo abgerufen, dort steht klar und deutlich :

Gelesene Konfigdateien u.a.:

Code:
/etc/php5/apache2/conf.d/odbc.ini
Ein exemplarischer Fehler sieht zBsp so aus :

Code:
Warning: odbc_fetch_row(): supplied argument is not a valid ODBC result resource in /etc/skripte/warengruppen-kontrolle.php on line 40
Line 40 ist dabei der CONNECT Befehl. - Anbei nochmals bemerkt, führe ich das ganze jetzt und hier manuell aus, läuft es.

LG Stefan
 
Morgen, du hast die Anleitung leider nicht verlinkt.

Vergleich doch mal die Ausgaben von auf cmd und als cron ausgeführt, evtl fehlt eine Environment-Variable.
Code:
headcrash@atlantis:~/skriptEcke$ cat env.php
<?PHP
print_r($_ENV)
?>
headcrash@atlantis:~/skriptEcke$ php env.php
Array
(
    [TERM] => xterm
    [SHELL] => /bin/bash
    [SSH_CLIENT] => x.x.x.x 46025 22
    [SSH_TTY] => /dev/pts/1
    [USER] => headcrash
    [LS_COLORS] => no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.svgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:
    [MAIL] => /var/mail/headcrash
    [PATH] => /home/headcrash/bin:/usr/local/bin:/usr/bin:/bin:/usr/games
    [PWD] => /home/headcrash/skriptEcke
    [LANG] => de_DE.UTF-8
    [HISTCONTROL] => ignoredups
    [SHLVL] => 1
    [HOME] => /home/headcrash
    [LOGNAME] => headcrash
    [SSH_CONNECTION] => x.x.x.x 46025 y.y.y.y 22
    [LESSOPEN] => | /usr/bin/lesspipe %s
    [LESSCLOSE] => /usr/bin/lesspipe %s %s
    [_] => /usr/bin/php
    [OLDPWD] => /home/headcrash
)

mfg
HeadCrash
 
Hi Head,

ich war mir sicher ich hätte den Link gesetzt .. ? Nun gut.

Die ENVs sehen ganz gut aus - ich finde wenigstens keinen grossen Anstoss - ausgeführt als root :

Code:
asterisk:/tmp# php test.php                                                                                                                                                      
Array
(
    [TERM] => vt102
    [SHELL] => /bin/bash
    [SSH_CLIENT] => x.x.x.x 49223 22
    [SSH_TTY] => /dev/pts/7
    [USER] => root
    [LS_COLORS] => 
    [MAIL] => /var/mail/root
    [PATH] => /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    [PWD] => /tmp
    [LANG] => de_DE@euro
    [PS1] => \h:\w\$ 
    [SHLVL] => 1
    [HOME] => /root
    [LS_OPTIONS] => --color=auto
    [LOGNAME] => root
    [SSH_CONNECTION] => 10.0.0.132 49223 10.0.0.60 22
    [_] => /usr/bin/php
    [OLDPWD] => /root
)

Als cron sieht es so aus ... Was kann ich mit "_" => php anfangen? Fehlt da nicht etwas?

Code:
Array
(
    [SHELL] => /bin/sh
    [PATH] => /usr/bin:/usr/sbin:/sbin:/bin
    [PWD] => /root
    [LANG] => de_DE.UTF-8
    [SHLVL] => 1
    [HOME] => /root
    [LOGNAME] => root
    [_] => /usr/bin/php
)

Ich habe mich dann mal gerade in saubere(re) PHP Lösungen eingelesen und diese Env-Deklaration gefunden :

Code:
putenv("ODBCINI=/etc/odbc.ini");

Das wäre doch eigentlich alles was ich benötige, ggf. noch ein php ENV, aber da php beim lesen der ENV Dekl. schon läuft ist es witzlos die Dekl. im PHP Code zu machen...

Was meinst Du? Wie sollte eine saubere Deklaration zu Beginn eines jeden PHP Codes mit Zugriff auf andere Komponenten Deiner Meinung nach aussehen?

LG und an dieser Stelle DANKE - Stefan
 
Mahlzeit,

Umgebungsvariablen kann man eigentlich jederzeit setzen (bitte widersprich mir wer, falls ich mich irre),
ich würde die Umgebungsvariable entweder direkt in der crontab oder am Anfang des Shell-Skriptes setzen und aus dem PHP-Code vernhalten.

Wahrscheinlich würde ich es mit ins Skript packen, einfach damit keine anderen Jobs beeinflußt werden und damit ich im Skript sehe ich brauche diese und jene Vorraussetzungen.

Mich wundert nur, dass er ODBCINI nicht als Variable anzeigt, wenn du das Skript als root startest.

Zu der Variablen "_", hier wird der letzte ausgeführte Befehl gespeichert.

mfg
HeadCrash
 
Hi Head,

Ok, die "_" hatte ich ebenso interpretiert. Ich habe mich hier vorhin nochmals kurz an das MAN für odbc und php gesetzt, er erwartet ausserhalb der PaketDistri die INI in /usr/share/etc/odbc.ini - dort ist nun auch ein symlink.

Ich kann das ganze aktuell nicht testen, hole es aber nach sobald es geht.

Ich denke ich setze die Umgebungsvariablen ersteinmal in den crontab - so hält sich der Aufwand für ein ungewisses Ende in Grenzen.

Was mich um so mehr verwirrt ist - meine zahlreichen Abfrageskripte (so um die 20) laufen hier bereits seit 2 Jahren, die Fehler erhalte ich erst seit einigen Wochen und / oder Monaten, auch nicht von allen Skripten. Ich vermute das es noch ein anderes Problem gibt (Umlaute? UTF-8?)

Ich beobachte mal fleißig. Anbei - hier gibt es ein fast baugleiches problem (allerdings ohne direkten Nutzen für unseren Thread)
 
Head und alle Mitlesenden,

ich war so froh etwas Licht in den Dschungel gebracht zu haben - doch am Mo. morgen kamen wieder die Cronjobs....

egal welches statement...
Code:
Warning: odbc_fetch_row(): supplied argument is not a valid ODBC result resource in /etc/skripte/warengruppen-kontrolle.php on line 88

Query Start -->
Code:
$query ="SELECT AK.Liefertag, AK.Kundennummer, ArP.Artikelnummer, ArP.Menge ";
$query.="WHERE ArP.Artikelnummer <> 70 ";
$query.="AND ArP.Menge < -100 ";
$query.="AND ArP.SA = 'R' ";
$query.="AND ArP.Auftragsnummer = AK.Auftragsnummer ";
$query.="AND AK.Liefertag > '2010-01-02'";
Query Ende -->

und auch...(wasn das?)
Code:
Warning: odbc_exec(): SQL error: [unixODBC][FreeTDS][SQL Server]Error converting characters into server's character set. Some character(s) could not be converted, SQL state S1000 in SQLExecDirect in /etc/skripte/warengruppen-kontrolle.php on line 82

Query Start -->
Code:
$query = "SELECT Datum, Kasse, Konto, Brutto FROM Journal WHERE Brutto > 3000 AND Datum > '2010-01-01' ORDER BY Datum";
Query Start -->

WICHTIG

In der gleichen PHP Datei werden aber auch Abfragen ausgeführt (!!), siehe hier :

Code:
$query = "SELECT Datum, Kasse, Kundenzahl FROM Kundenzahl WHERE Kundenzahl > 1200 ORDER BY Datum";

Ergebnis :

Code:
Datum Kasse Kundenzahl
2008-09-29 00:00:00.000 25 2674
??

Also keine externen Einflüsse, oder wie?
Dank Euch für Eure Zeit!

Stefan
 
Zurück
Oben