[Bash] Configdateien?

  • Thread starter Thread starter counteam
  • Start date Start date
C

counteam

Guest
Huhu.
Ich bin gerade dabei, ein kleines Bash/Shellscript zu basteln.

Da ich neben den eigendlichen Bashscript eine Config-Datei haben möchte, wo der Benutzer diverse Variablen verändern kann (Beispielsweise Datenbank-Zugänge), damit er nicht im eigendlichen Teil des Scriptes gerumfummeln muss.

Wie mache ich dies nun?
Mittels source (bzw. .) funktioniert es nicht.
Kann mir jemand ein Beispiel geben?

PHP:
#!/bin/bash
CONFIG="/var/www/config.ini"
source $CONFIG

echo "Variable aus der Config"
echo "DB-Host: $DATABASE_HOSTNAME"
echo "DB-User: $DATABASE_USERNAME"
 
Hallo!

script.sh
PHP:
#!/bin/bash
CONFIG="./config.sh"
source $CONFIG

echo "Variable aus der Config"
echo "DB-Host: $DATABASE_HOSTNAME"
echo "DB-User: $DATABASE_USERNAME"

config.sh
PHP:
#!/bin/bash

DATABASE_HOSTNAME="host"
DATABASE_USERNAME="user"
 
script_sourcefile.conf
Code:
#!/bin/bash
ICH_BIN="Ich bin eine Sourcefile"

Script Variante1
Code:
# Source includen
 . ./script_sourcefile.conf
 echo "$ICH_BIN"

Script Variante2
Code:
# Source includen
 source ./script_sourcefile.conf
 echo "$ICH_BIN"

Du kannst natürlich auch noch Checks einbauen, aber das ist ein Anderes Thema.

MfG
Impact
 
Last edited by a moderator:
Wie schaut es mit der ausführbarkeit aus?
Muss nur das eigendliche Script ausführbare rechte (+x) haben, oder auch die config-file?

Danke schonmal, ich proiere es gleich mal aus.

EDIT:
Funktionieren tut dies nicht.
Wenn ich in der Config keinen Shebang setze (/bin/bash), so bekomme ich folgende Ausgabe:
server:/var/www/webpanel/install# ./setup.sh
Variable aus der Config
DATABASE_DATABASE=webpanel
DB-User:

Wenn ich nun nen Shebang setze, so bekomme ich folgende ausgabe:
server:/var/www/webpanel/install# ./setup.sh
Variable aus der Config
DB-Host:
DB-User:

Hier nochmals die aktuellen Dateien:
setup.sh (rwsrwsrwt, 7777)
PHP:
#!/bin/bash
CONFIG="./config.sh"
source $CONFIG

echo "Variable aus der Config"
echo "DB-Host: $DATABASE_HOSTNAME"
echo "DB-User: $DATABASE_USERNAME"

config.sh (rwsrwsrwt, 7777)
PHP:
#!/bin/bash
DATABASE_HOSTNAME="localhost"
DATABASE_USERNAME="root"
DATABASE_PASSWORD="1234"
DATABASE_DATABASE="webpanel"
 
Last edited by a moderator:
functions.sh
Code:
#  ****************************************************************************
#  *                               functions.sh                               *
#  *                           --------------------                           *
#  *     Copyright (C) 2001-2011 Markus Kohlmeyer <rootservice@gmail.com>     *
#  *                                                                          *
#  ****************************************************************************
#  *                                                                          *
#  *   License GPLv2: GNU GPL version 2  <http://gnu.org/licenses/gpl.html>   *
#  *      This is free software: You are free to change and redistribute      *
#  *      it under the terms of the GNU General Public License version 2      *
#  *           There is NO WARRANTY, to the extent permitted by law           *
#  *                                                                          *
#  ****************************************************************************
#

function getopt_simple() {
  until [ -z "${1}" ]
  do
    case "${1}" in
      --*=*)
        local tmpopt="${1:2}"
        local cmdopt="${tmpopt%%=*}"
        local cmdval="${tmpopt##*=}"
        for allowed in "${ALLOWEDOPTS[@]}"
        do
          if [ "${allowed}" = "${cmdopt}" ]
          then
            eval ${cmdopt}="${cmdval}"
          fi
        done
      ;;
      --version|-V) show_version;;
      --help|-h|*) show_usage;;
    esac
    shift
  done
  return
}

function getopt_arrays() {
  until [ -z "${1}" ]
  do
    case "${1}" in
      --*=*)
        local tmpopt="${1:2}"
        local cmdopt="${tmpopt%%=*}"
        local cmdval="${tmpopt##*=}"
        for allowed in "${ALLOWEDOPTS[@]}"
        do
          if [ "${allowed}" = "${cmdopt}" ]
          then
            cmdopts_arr=( "${cmdopts_arr[@]}" "${tmpopt}" )
            cmdopt_arr=( "${cmdopt_arr[@]}" "${cmdopt}" )
            cmdval_arr=( "${cmdval_arr[@]}" "${cmdval}" )
          fi
        done
      ;;
      --version|-V) show_version;;
      --help|-h|*) show_usage;;
    esac
    shift
  done
  return
}

function read_prompt() {
  read -p "$(echo -en "\E[1;37m${1}\E[0m " >&2)" "${2:-REPLY}"
#   until [ -z $(echo "${2:-REPLY}" | tr -d [:print:]) ]
#   do
#     show_warn "non-printable char(s) detected! Please retry...\n"
#     read_prompt "${1}" "${2}"
#   done
  return
}

function read_passwd() {
  read -s -p "$(echo -en "\E[1;37m${1}\E[0m " >&2)" "${2:-REPLY}"
#   until [ -z $(echo "${2:-REPLY}" | tr -d [:print:]) ]
#   do
#     show_warn "non-printable char(s) detected! Please retry...\n"
#     read_prompt "${1}" "${2}"
#   done
  return
}

function show_text() {
  echo -en "\E[1;37m${1}\E[0m" >&2
  return
}

function show_info() {
  echo -en "\E[1;32m${1}\E[0m" >&2
  return
}

function show_warn() {
  echo -en "\E[1;33m${1}\E[0m" >&2
  return
}

function show_error() {
  echo -en "\E[1;31m${1}\E[0m" >&2
  return
}

function show_usage() {
  echo "Usage: $(basename ${0}) [OPTIONS]

OPTIONS:
${USAGEOPTIONS}
      --help       display this help and exit
      --version    output version information and exit

Report any bugs to: ${CONTACT}
" >&2
  exit 1
}

function show_version() {
  echo "$(basename ${0}) ${VERSION}
${COPYRIGHT}
License GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>
This is free software: You are free to change and redistribute
it under the terms of the GNU General Public License version 2.
There is NO WARRANTY, to the extent permitted by law.

Written by ${AUTHORS}
" >&2
  exit 1
}

function rootonly() {
  if [ "${UID}" != "0" ] || [ "${EUID}" != "0" ]
  then
    show_error "You must be root to run this script!"
  fi
  return
}

script_template.sh
Code:
#!/bin/bash
TZ=UTC0;LC_ALL=C
shopt -s extglob
#  ****************************************************************************
#  *                            script_template.sh                            *
#  *                          ----------------------                          *
#  *     Copyright (C) 2001-2011 Markus Kohlmeyer <rootservice@gmail.com>     *
#  *                                                                          *
#  ****************************************************************************
#  *                                                                          *
#  *   License GPLv2: GNU GPL version 2  <http://gnu.org/licenses/gpl.html>   *
#  *      This is free software: You are free to change and redistribute      *
#  *      it under the terms of the GNU General Public License version 2      *
#  *           There is NO WARRANTY, to the extent permitted by law           *
#  *                                                                          *
#  ****************************************************************************
#

# Declare variables

VERSION="0.0.1"
AUTHORS="Markus Kohlmeyer"
CONTACT="<rootservice@gmail.com>"
COPYRIGHT="Copyright (C) 2001-2011 Markus Kohlmeyer"

ALLOWEDOPTS=( var1 var2 var3 )
USAGEOPTIONS="
  --var1=VALUE     explain var1
  --var2=VALUE     explain var2
  --var3=VALUE     explain var3
"

##########################################################
###### !!! DO NOT EDIT ANYTHING BELOW THIS LINE !!! ######
##########################################################

FUNCTIONSFILE="./functions.sh"

if [ -f ${FUNCTIONSFILE} ]
then
  . ${FUNCTIONSFILE}
else
  echo -e "\E[1;31mFile \"${FUNCTIONSFILE}\" not found!\E[0m" >&2
  exit 1
fi

##########################
###### Main section ######
##########################

rootonly

if [ "${#ALLOWEDOPTS[@]}" -gt "0" ]
then
  getopt_simple "${@}"
fi

exit 0

Beide chmod 0755 und ich habe keine Probleme auf meinen Systemen.

Bitte die Funktionen nicht einfach Blind übernehmen, die sind nur zu Demonstrationszwecken gedacht.
 
Funktionieren tut dies nicht, auch wenn es dem gleicht, was ich habe.
Die "functions.sh" existiert ja, sonst würde die Shell ja ausgeben, dass die Datei nicht existiert. Die Funktionen selber die aufgerufen werden (rootonly & getopt_simple) findet er aber nicht, obwohl diese existieren.

Ich frage mich, warum es nicht funktioniert. Liegt es am OS?

setup.sh (755, root:root)
#!/bin/bash
FUNCTIONSFILE="./functions.sh"

if [ -f ${FUNCTIONSFILE} ]
then
. ${FUNCTIONSFILE}
else
echo -e "\E[1;31mFile \"${FUNCTIONSFILE}\" not found!\E[0m" >&2
exit 1
fi

rootonly
exit 0

functions.sh (755, root:root)
#!/bin/bash
function rootonly() {
echo "root only!"
}
 
Last edited by a moderator:
Was sagt denn ein
Code:
bash -v setup.sh

PHP:
FUNCTIONSFILE="./functions.sh"

. $FUNCTIONSFILE
}unctionecho "root only!"


tester
setup.sh: line 7: tester: command not found
exit 0

Nicht wundern, warum die klasse nun "tester" heißt. Habe die Testweise umbenannt (diese macht einfach nur eine ausgabe)
 
Es funktioniert - Habe den Fehler gefunden.
Da ich mit Notepad++ arbeite, in den Einstellungen aber Das Dateiformat "Windows" angewählt war, musste ich dies zu "Unix" umstellen.

Liegt wahrscheinlich an den Zeilenumbrüchen (?)
 
Der Shebang #!/bin/bash kann bei der sourcefile entfallen.

EDIT: Normal hätte mehr als ein Fehler kommen müssen, da schon bei der Funktionsdefinition Fehler durch CR LF auftreten.

Den Fehler machen oft Leute. Unter anderem sollte es beim Auführen von der setup.sh auch einen Fehler geben, da der Shebang mit CR LF am Ende fehlinterpretiert wird.

Die Sourcefile muss auch nicht ausführbar sein. Der Inhalt der Sourcefile wird durch den Interpreter automatisch im Script eingesetzt. Aus diesem Grund ist auch das Shebang im Sourcefile nutzlos.

Mit einem vernünftigen FTP-Client wäre der Fehler nicht aufgefallen, da dieser Textdateien automatisch anhand der Dateiendung erkennt und diese im ASCII-Modus mit 7 Bit überträgt. Dadurch wird auch das Problem mit dem Zeilenende umgangen.

Unter Linux gibt es unter anderem auch das Tool dos2unix. Das Paket ist unter Debian gleichnamig.
 
[GELÖST] [Bash] Configdateien?

OK, danke.

Mit dem dos2unix hatte ich es bereits probiert gehabt, funktionierte aber dementsprechend nicht.

Beim nächstenmal achte ich darauf, das die Datei dementsprechend für das Betriebssystem abgespeichert wird.

Das mit dem FTP-Programm ist mir neu. Benutze WinSCP - Gibt es auch hierfür einstellungen?
 
...und diese im ASCII-Modus mit 7 Bit überträgt. Dadurch wird auch das Problem mit dem Zeilenende umgangen.
Was aber absolut keinen Einfluss auf das Format der Zeilenenden hat, da sowohl LF als auch CR zum ASCII-Standard gehören und 7Bit (0001010 und 0001101) sind.
 
Hast recht, die Konvertierung wird dennoch vom FTP-Programm vorgenommen. Du scheinst noch nicht soviel Praxiserfahrung zu haben.

Erstelle eine Textdatei im Windows-Format (CR LF) und übertrage diese im ASCII-Modus mit deinem FTP-Programm auf deinen Server. Dann sieh dir danach die Datei an. Wenn du es immer noch nicht glauben willst, dann google mal nach "ASCII CR LF FTP". Unter anderem wirst du auch eine Erklärung finden, warum das so ist. Das hat nichts mit Pfuschen zu tun. Es handelt sich um einen Standard, der schon Jahrelang angewendet wird.

Die meisten wissen nix mit dem ASCII-Modus anzufangen und denken Binary wäre für Textdateien generell besser.

Wenn man selbst darauf achtet, wie Textdateien formatiert sind, stellt das auch kein Problem dar. Aber wehe es passiert sowas wie mit dem Shell-Script.
 
Last edited by a moderator:
Das hat nichts mit Pfuschen zu tun. Es handelt sich um einen Standard, der schon Jahrelang angewendet wird.
Nur weils seit langem benutzt wird, heisst das nicht, dass das auch so richtig ist. Der ASCII Mode wurde eingeführt weil damals die Übertragsungsgeschwindigkeit extrem gering war (paar hundert bits per sec) und war somit nur ein workaround der heute obsolet ist.

Wem der FTP Client mal Binärdateien zerschossen hat weil er meinte es wären Plaintext Dateien gewesen, der wird mir recht geben.

Deshalb eben meine Meinung: FTP sollte die Dateien übertragen, und nicht darin rumpfuschen, denn FTP heisst File Transfer Protocol und nicht File Transfer And Modify Protocol.

Und wer mit jetzt mit CRLF <> LF kommt dem sage ich: kümmer dich selbst drum :)

Aber wehe es passiert sowas wie mit dem Shell-Script.
Binary als ASCII übertragen ist aber das viel größere Übel.
 
Ich zitiere dann mal RFC959:
Code:
   2.2.  TERMINOLOGY
...
      End-of-Line

         The end-of-line sequence defines the separation of printing
         lines.  The sequence is Carriage Return, followed by Line Feed.
...

         3.1.1.1.  ASCII TYPE
...
            In accordance with the NVT standard, the <CRLF> sequence
            should be used where necessary to denote the end of a line
            of text.  (See the discussion of file structure at the end
            of the Section on Data Representation and Storage.)
...

Soviel zum Thema Standard...
 
Es wird Zeit, dass Windows CR+LF endlich aufgibt. Niemand würde es vermissen. Obwohl synthaktisch korrekt, ist die Zeit der Schreibmaschinen und Rohtext-Drucker vorbei. Heute ist es einfach nur noch ein sinnloses, zusätzliches Bit.
 
Binary als ASCII übertragen ist aber das viel größere Übel.

Wer macht denn sowas? Mit einem vernünftigen FTP-Client passiert das nicht. Es seiden der User ist so blöd und verwendet für eine Birnärdatei die Dateiendung .txt oder .sh. Selbst wenn in einem Shellscript Binärcode enthalten ist, ist dieser mit base64 codiert und die Übertragung hat absolut keinen Einfluss.

Code:
echo -e '#!'"$(which bash)\nbase64 -d >~/copy_of_echo.bin <<EOF\n$(base64 `which echo`)\nEOF\nmd5sum ~/copy_of_echo.bin `which echo`" > echo.sh

Datei einmal per FTP runterladen und dann das Format auf CR+LF umstellen. Danach im ASCII-Modus per FTP übertragen und einmal ausführen -> gleicher Hashwert

Ich nutze seit 10 Jahren die Automatische Erkennung zwischen ASCII und Binary. Mir ist bis jetzt noch keine einzige Binärdatei deswegen falsch übertragen worden. Ich würde mich daran erinnern, wenn mir sowas mal passiert wäre.

Im Gegenteil, der Modus hat mich schon oftmals vor Programmieren geschützt, die Perl-Scripts gerne mit Windows-Editoren schreiben und oft nicht an die Konvertierung denken. Letztendlich kann man so ein Problem auch selbst eben schnell beheben, aber es ist dennoch zusätzlicher Aufwand.

PS: Ich hab schon oft geschrieben, dass sich Windows noch in der Steinzeit befindet. Ursprünglich kommt CR+LF von elektrisch betriebenen Schreibmaschinen. CR -> Kopf auf Position 0 bewegen -> LF -> Nächste Zeile.
 
Last edited by a moderator:
Back
Top