michahe
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 857
|
Hallo,
ich habe in der BASH einen SQL-Befehl zur Erzeugung einer Liste; die Variable txtAutor wird vom Script durch das Auslesen von Dateinamen erzeugt:
| #!bin bash
$ txtAutor="Peter Witz"
$ psql -U "user" -d "SchemaName" --no-align --tuples-only -c "SELECT \"ID-Mus\" FROM \"SchemaName\".\"T TabellenName\" WHERE \"Autor\" = '$txtAutor'";
|
So weit funktioniert das. Aber es gibt auch:
$ txtAutor="Peter O'Brian"
Dort funktioniert es nicht weil den Apostroph (') doppeln (und quoten?) muss. Wie lautet dafür die korrekte Syntax?
|
michahe
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 857
|
Habe eine Lösung:
$$$ psql -U "user" -d "SchemaName" --no-align --tuples-only -c "SELECT \"ID-Mus\" FROM \"SchemaName\".\"T Tabelle\" WHERE \"Autor\" = '$(echo ${txtAutor//\'/\'\'})'"
Gibt es Verbesserungsvorschläge?
Danke!
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4694
Wohnort: Berlin
|
Funktioniert das hier?
| psql -U 'user' -d 'SchemaName' --no-align --tuples-only --set "txtAutor=$txtAutor" -c 'SELECT "ID-Mus" FROM "SchemaName"."T TabellenName" WHERE "Autor" = :txtAutor;'
|
Wobei psql kein sinnvolles Werkzeug für so etwas ist wenn das nicht funktioniert, weil man kein SQL als Zeichenketten zusammenbastelt, schon gar nicht wenn Werte dafür von aussen kommen.
|
shiro
Supporter
Anmeldungsdatum: 20. Juli 2020
Beiträge: 1274
|
michahe schrieb: Gibt es Verbesserungsvorschläge?
Es gibt die bash Funktion "quote", die eventuell weiter helfen kann
$ txtAutor=$(quote "Peter O'Brian")
$ echo $txtAutor
'Peter O'\''Brian'
$ psql -U "user" -d "SchemaName" --no-align --tuples-only -c "SELECT \"ID-Mus\" FROM \"SchemaName\".\"T Tabelle\" WHERE \"Autor\" = $txtAutor"
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13213
|
Ein anderer Ansatz wäre vielleicht PREPARE zu nutzen.
|
Doc_Symbiosis
Anmeldungsdatum: 11. Oktober 2006
Beiträge: 4453
Wohnort: Göttingen
|
Und viele der Backslashes zum Escapen könntest Du Dir sparen, wenn Du einfach Single-Quotes statt Double-Quotes verwenden würdest, glaube ich zumindest. Also, ich kenne das gar nicht, dass so viele Double-Quotes in psql verwendet werden, außer die äußeren umschließenden.
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4694
Wohnort: Berlin
|
@Doc_Symbiosis: Das kann man sich in SQL nicht aussuchen, die beiden bedeuten etwas unterschiedliches. ' sind für Zeichenketten und " sind für Namen damit man da auch Sonderzeichen wie Leerzeichen oder - verwenden kann, und auch SQL-Schlüsselworte. Also mindestens bei ID-Mus und T Tabelle müssen die " sein, sonst ist das syntaktisch falsch. Und es gibt Leute die einfach aus Gewohnheit/zur Sicherheit alle Namen in " einschliessen. Dann kann man zum Beispiel auch sicher sein, das eine neue SQL oder Datenbankversion nicht durch ein neues Schlüsselwort vielleicht vorhandenes SQL ungültig wird.
|
michahe
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 857
|
Marc_BlackJack_Rintsch schrieb: Funktioniert das hier?
| psql -U 'user' -d 'SchemaName' --no-align --tuples-only --set "txtAutor=$txtAutor" -c 'SELECT "ID-Mus" FROM "SchemaName"."T TabellenName" WHERE "Autor" = :txtAutor;'
|
Leider nicht: Syntaxfehler bei »:« (Code: :txtAutor)
|
michahe
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 857
|
shiro schrieb: Es gibt die bash Funktion "quote", die eventuell weiter helfen kann
Leider nicht:
$ txtAutor=$(quote "Peter O'Brian")
bash: quote: Kommando nicht gefunden.
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4694
Wohnort: Berlin
|
quote ist bei mir definiert, frag mich aber nicht wo das her kommt:
$ type quote
quote is a function
quote ()
{
local quoted=${1//\'/\'\\\'\'};
printf "'%s'" "$quoted"
}
|
shiro
Supporter
Anmeldungsdatum: 20. Juli 2020
Beiträge: 1274
|
michahe schrieb: Leider nicht:
$ txtAutor=$(quote "Peter O'Brian")
bash: quote: Kommando nicht gefunden.
Schau mal nach, ob bei dir das Script
ausgeführt wird. Ein Tip: Schau dir mal an, was $ bash -x -l -i ausgibt.
|
michahe
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 857
|
Marc_BlackJack_Rintsch schrieb: quote ist bei mir definiert ...
Hier nicht:
$ type quote
bash: type: quote: Nicht gefunden
shiro schrieb: Ein Tip: Schau dir mal an, was $ bash -x -l -i ausgibt.
ca. 900 Zeilen, darin habe ich nach "completion" gesucht:
++ PROMPT_COMMAND+=('printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"')
++ [[ -r /usr/share/bash-completion/bash_completion ]]
+ unset TERMCAP
+ unset MANPATH
+ [[ -f /home/meinname/.bashrc ]]
+ . /home/meinname/.bashrc
++ [[ himxBH != *i* ]]
++ '[' -r /usr/share/bash-completion/bash_completion ']' Schau mal nach, ob bei dir das Script
ausgeführt wird.
/usr/share/bash-completion/ existiert, mit 257 Elementen in /usr/share/bash-completion/completions/, aber kein "quote". Wenn ich die Funktion in mein Skript einbauen möchte, wäre folgender Ansatz korrekt:
FUNC_QuoteApostroph ()
{
local quoted=${1//\'/\'\\\'\'};
printf "'%s'" "$quoted"
} und
$ txtAutor="Peter O'Brian"
$ txtAutor=FUNC_QuoteApostroph(txtAutor)
|
shiro
Supporter
Anmeldungsdatum: 20. Juli 2020
Beiträge: 1274
|
++ [[ -r /usr/share/bash-completion/bash_completion ]]
Das sieht so aus, als ob das Script nicht ausgeführt wird, denn es folgt danach kein sourcen (.) des scripts. Ist deinem User das Leserecht für die Datei entzogen? Es sollte eigentlich so aussehen, wie der Aufruf von .bashrc darunter. Es sollte eigentlich folgendes existieren:
$ ls -l /usr/share/bash-completion/bash_completion
-rw-r--r-- 1 root root 77071 Nov 15 2021 /usr/share/bash-completion/bash_completion
$ grep -A4 -B1 "^quote()" /usr/share/bash-completion/bash_completion
# This function shell-quotes the argument
quote()
{
local quoted=${1//\'/\'\\\'\'}
printf "'%s'" "$quoted"
}
$ $ txtAutor="Peter O'Brian"
$ txtAutor=FUNC_QuoteApostroph(txtAutor)
Was machst du da? Wenn du "FUNC_QuoteApostroph" als bash Funktion deklarierst, darfst du doch keine Klammern zur Parameter-Übergabe nutzen. Gemäß bash wäre dann korrekter:
$ txtAutor="Peter O'Brian"
$ txtAutor=$(FUNC_QuoteApostroph "$txtAutor")
$ echo $txtAutor
'Peter O'\''Brian'
$
|
michahe
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 857
|
shiro schrieb: ++ [[ -r /usr/share/bash-completion/bash_completion ]]
Das sieht so aus, als ob das Script nicht ausgeführt wird, denn es folgt danach kein sourcen (.) des scripts. Ist deinem User das Leserecht für die Datei entzogen? Es sollte eigentlich so aussehen, wie der Aufruf von .bashrc darunter. Es sollte eigentlich folgendes existieren:
$ ls -l /usr/share/bash-completion/bash_completion...
>
Nein, bei mir schaut es so aus:
tree /usr/share/bash-completion/
/usr/share/bash-completion/
├── completions
│ ├── adb
│ ├── addpart
│ ├── aria2c
│ ├── blkdiscard
│ ├── blkid
│ ├── blkzone
│ ├── blockdev
│ ├── bluetooth -> tlp
│ ├── bootctl
│ ├── btrfs
│ ├── busctl
│ ├── bwrap
│ ├── cal
│ ├── calf
│ ├── cfdisk
│ ├── chcpu
│ ├── chfn
│ ├── chmem
│ ├── chrt
│ ├── chsh
│ ├── col
│ ├── colcrt
│ ├── colormgr
│ ├── colrm
│ ├── column
│ ├── coredumpctl
│ ├── cpupower
│ ├── ctrlaltdel
│ ├── dbus-send
│ ├── dconf
│ ├── delpart
│ ├── devlink
│ ├── dmesg
│ ├── eject
│ ├── fadvise
│ ├── fallocate
│ ├── fastboot
│ ├── fdisk
│ ├── fincore
│ ├── findfs
│ ├── findmnt
│ ├── firewall-cmd
│ ├── flock
│ ├── fsck
│ ├── fsck.cramfs
│ ├── fsck.minix
│ ├── fsfreeze
│ ├── fstrim
│ ├── fwupdmgr
│ ├── fwupdtool
│ ├── gapplication
│ ├── gdal2tiles.py -> gdalinfo
│ ├── gdal2xyz.py -> gdalinfo
│ ├── gdaladdo -> gdalinfo
│ ├── gdalbuildvrt -> gdalinfo
│ ├── gdal_calc.py -> gdalinfo
│ ├── gdalchksum.py -> gdalinfo
│ ├── gdalcompare.py -> gdalinfo
│ ├── gdal-config -> gdalinfo
│ ├── gdal_contour -> gdalinfo
│ ├── gdal_create -> gdalinfo
│ ├── gdaldem -> gdalinfo
│ ├── gdal_edit.py -> gdalinfo
│ ├── gdalenhance -> gdalinfo
│ ├── gdal_fillnodata.py -> gdalinfo
│ ├── gdal_grid -> gdalinfo
│ ├── gdalident.py -> gdalinfo
│ ├── gdalimport.py -> gdalinfo
│ ├── gdalinfo
│ ├── gdallocationinfo -> gdalinfo
│ ├── gdalmanage -> gdalinfo
│ ├── gdal_merge.py -> gdalinfo
│ ├── gdalmove.py -> gdalinfo
│ ├── gdal_polygonize.py -> gdalinfo
│ ├── gdal_proximity.py -> gdalinfo
│ ├── gdal_rasterize -> gdalinfo
│ ├── gdal_retile.py -> gdalinfo
│ ├── gdal_sieve.py -> gdalinfo
│ ├── gdalsrsinfo -> gdalinfo
│ ├── gdaltindex -> gdalinfo
│ ├── gdaltransform -> gdalinfo
│ ├── gdal_translate -> gdalinfo
│ ├── gdal_viewshed -> gdalinfo
│ ├── gdalwarp -> gdalinfo
│ ├── gdbus
│ ├── getopt
│ ├── gio
│ ├── git
│ ├── gresource
│ ├── grub
│ ├── gsettings
│ ├── gst-inspect-1.0
│ ├── gst-launch-1.0
│ ├── hardlink
│ ├── hexdump
│ ├── homectl
│ ├── hostnamectl
│ ├── hwclock
│ ├── hwloc
│ ├── img2sixel
│ ├── inkscape
│ ├── ionice
│ ├── ipcmk
│ ├── ipcrm
│ ├── ipcs
│ ├── irqtop
│ ├── isosize
│ ├── journalctl
│ ├── kernel-install
│ ├── kmod
│ ├── last
│ ├── lastb -> last
│ ├── ldattach
│ ├── lilv
│ ├── localectl
│ ├── logger
│ ├── loginctl
│ ├── look
│ ├── losetup
│ ├── lsar
│ ├── lsblk
│ ├── lscpu
│ ├── lsinitcpio -> mkinitcpio
│ ├── lsipc
│ ├── lsirq
│ ├── lslocks
│ ├── lslogins
│ ├── lsmem
│ ├── lsns
│ ├── machinectl
│ ├── makepkg -> pacman
│ ├── mbimcli
│ ├── mcookie
│ ├── mesg
│ ├── mkfs
│ ├── mkfs.bfs
│ ├── mkfs.cramfs
│ ├── mkfs.minix
│ ├── mkinitcpio
│ ├── mkswap
│ ├── mmcli
│ ├── more
│ ├── mount
│ ├── mountpoint
│ ├── mpv
│ ├── namei
│ ├── networkctl
│ ├── newgrp
│ ├── nfc -> tlp
│ ├── nmcli
│ ├── nsenter
│ ├── ogr2ogr -> gdalinfo
│ ├── ogrinfo -> gdalinfo
│ ├── ogrlineref -> gdalinfo
│ ├── ogrmerge.py -> gdalinfo
│ ├── ogrtindex -> gdalinfo
│ ├── oomctl
│ ├── openconnect
│ ├── p11-kit
│ ├── pacat -> pactl
│ ├── pacman
│ ├── pacman-key -> pacman
│ ├── pactl
│ ├── padsp -> pactl
│ ├── pamac
│ ├── paplay -> pactl
│ ├── parec -> pactl
│ ├── parecord -> pactl
│ ├── partx
│ ├── patool
│ ├── pg
│ ├── pip
│ ├── pipesz
│ ├── pivot_root
│ ├── poetry
│ ├── portablectl
│ ├── powertop
│ ├── prlimit
│ ├── pulseaudio -> pactl
│ ├── pygmentize
│ ├── qmicli
│ ├── qpdf
│ ├── readprofile
│ ├── rename
│ ├── renice
│ ├── resizepart
│ ├── resolvectl
│ ├── rev
│ ├── rfkill
│ ├── rtcwake
│ ├── runuser -> su
│ ├── script
│ ├── scriptlive
│ ├── scriptreplay
│ ├── setarch
│ ├── setpriv
│ ├── setsid
│ ├── setterm
│ ├── sfdisk
│ ├── snap
│ ├── su
│ ├── swaplabel
│ ├── swapoff
│ ├── swapon
│ ├── systemctl
│ ├── systemd-analyze
│ ├── systemd-cat
│ ├── systemd-cgls
│ ├── systemd-cgtop
│ ├── systemd-cryptenroll
│ ├── systemd-delta
│ ├── systemd-detect-virt
│ ├── systemd-dissect
│ ├── systemd-id128
│ ├── systemd-nspawn
│ ├── systemd-path
│ ├── systemd-resolve
│ ├── systemd-run
│ ├── systemd-sysext
│ ├── taskset
│ ├── tc
│ ├── timedatectl
│ ├── tlp
│ ├── tlp-stat -> tlp
│ ├── tracker3
│ ├── trust
│ ├── tunelp
│ ├── uclampset
│ ├── udevadm
│ ├── udiskie
│ ├── udiskie-info
│ ├── udiskie-mount
│ ├── udiskie-umount
│ ├── udisksctl
│ ├── ufw
│ ├── ul
│ ├── umount
│ ├── unar
│ ├── unshare
│ ├── utmpdump
│ ├── uuidd
│ ├── uuidgen
│ ├── uuidparse
│ ├── waitpid
│ ├── wall
│ ├── wdctl
│ ├── whereis
│ ├── wifi -> tlp
│ ├── wipefs
│ ├── wl-copy
│ ├── wl-paste
│ ├── write
│ ├── wwan -> tlp
│ ├── x264
│ ├── xkbcli
│ ├── yt-dlp
│ └── zramctl
└── helpers
└── gst
3 directories, 258 files Wenn du "FUNC_QuoteApostroph" als bash Funktion deklarierst, darfst du doch keine Klammern zur Parameter-Übergabe nutzen. Gemäß bash wäre dann korrekter:
$ txtAutor="Peter O'Brian"
$ txtAutor=$(FUNC_QuoteApostroph "$txtAutor")
$ echo $txtAutor
'Peter O'\''Brian'
$
Danke! Ist mein Code zur FUNC_QuoteApostroph wenigstens richtig? Lass uns die bash_completion vergessen, ich würde die FUNC in meinen Code einbauen ...
|
shiro
Supporter
Anmeldungsdatum: 20. Juli 2020
Beiträge: 1274
|
Lass uns die bash_completion vergessen, ...
Ich denke, du hast das Paket "bash-completion" nicht installiert, was normalerweise automatisch erfolgt. Aber ok, lassen wir das.
Ist mein Code zur FUNC_QuoteApostroph wenigstens richtig?
Da ich kein "psql" verwende, habe ich mal kurz eine sqlite3 Datenbank erstellt und relevante Daten zum testen eingegeben. Dabei ist mir aufgefallen, dass ein einfaches Verdoppeln des Apostrophs eher zum Ziel führt. Beispiel:
$ FUNC_QuoteApostroph ()
{
local quoted=${1//\'/\'\'};
printf "'%s'" "$quoted"
}
$ txtAutor="Peter O'Brian"
$ txtAutor=$(FUNC_QuoteApostroph "$txtAutor")
$ echo $txtAutor
'Peter O''Brian'
$ sqlite3 xdb.db "select * from test where name = $txtAutor;"
2|Peter O'Brian|Mal sehen
$
$ # dagegen mit der ursprünglichen "quote" Funktion:
$ txtAutor="Peter O'Brian"
$ txtAutor=$(quote "$txtAutor")
$ echo $txtAutor
'Peter O'\''Brian'
$ sqlite3 xdb.db "select * from test where name = $txtAutor;"
Error: in prepare, unrecognized token: "\" (1)
$
Welche Variante bei "psql" zum Ziel führt, solltest du selbst ausprobieren. PS: Es geht noch etwas einfacher:
$ q(){ printf "'%s'" "${1//\'/\'\'}";}
$ txtAutor="Peter O'Brian"
$ sqlite3 xdb.db "select * from test where name = $(q "$txtAutor");"
2|Peter O'Brian|Mal sehen
$
|