És a /bin/bash le van cserélve egy olyan shellre, amely
!ls -l
!mc
!cat
mindent visz ilyen felkiáltójeles módon, de innentől az a shell trükk sem okoz problémát, hogy
In [1]: import json
In [2]: a = json.loads('{"alma": "piros", "körte": "zöld"}') # vagy json.load(filep)
In [3]: print (a['körte'])
zöld
In [4]: !echo $a
{alma: piros, körte: zöld}
In [5]: b = a['alma']
In [6]: !echo $b
piros
Nem tudom, mikor lesz ez jó és mikor nem, mindenesetre érdekes színfoltot hozott, így egyelőre próbaként lecseréltem erre az alapértelmezett shell-t.
- hg2ecz blogja
- A hozzászóláshoz be kell jelentkezni
Hozzászólások
Épp most kell Python kódot migrálnom Java-ra. Hát nem nyerte el a Python a tetszésem.
Mondjuk pozitív, mert kicsit eljátszogattam a jython-nal, hogy ugyanazokkal a tesztekkel a Python és a Java implementációt is tudjam tesztelni, az egész érdekes dolog volt.
Mindenesetre sok sikert a shell-hez, az is érdekesnek néz ki.
- A hozzászóláshoz be kell jelentkezni
Ez igazan akkor lenne jo, ha a szokasos shell parancsokat (azok megfelelojet) el lehetne erni kenyelmesen valamilyen liben keresztul. Ilyesmire gondolok pl:
import python_shell_cmds as psc
files=psc.ls('~')
for f in files:
psc.mv(f,f+'.old')
Sokszor kell bash-ben valamilyen parancs kimenetet parse-olni, azt meg lehetne uszni (ahogy az amugy nagyon fura powershellnel is meg van oldva, hogy objektumokat ad at).
When you tear out a man's tongue, you are not proving him a liar, you're only telling the world that you fear what he might say. -George R.R. Martin
- A hozzászóláshoz be kell jelentkezni
Ez ennyit tud:
In [11]: a = !ls -l
In [12]: a[1].split()
Out[12]:
['-rw-rw-r--',
'1',
'zsolt',
'zsolt',
'1075944251',
'aug',
'20',
'14:03',
'2020-08-20-raspios-buster-arm64.zip']
In [13]: a[1].split()[8]
Out[13]: '2020-08-20-raspios-buster-arm64.zip'
In [3]: files = !ls -1
In [4]: for f in files:
...: !mv $f $f".old"
...:
# átnevezte
... továbbra is ismerkedem vele.
- A hozzászóláshoz be kell jelentkezni
A szokásos shell parancsokat erőltetett módon el lehet érni a subprocess modul segítségével, de ha már az [I]Pythont használja az ember, akkor sokkal jobb a pathlib modul használata, amellyel a fájlnév-manipulációt op.rendszertől független módon végezhetjük. A pathlib modullal mindent elvégezhetünk, bár elsőre lehet, hogy kézreállóbbnak tűnik némely esetben az os- vagy az shutils modul valamely eljárásának az alkalmazása.
- A hozzászóláshoz be kell jelentkezni
Hasonlót megnéznék Rubyhoz, valahogy sokkal alkalmasabb nyelvnek tűnik erre. Igaz pipeline operátor még nincs, bár igény volna rá.
Illetve van is ilyen, igaz a pipe-ot csak a saját típusán belül tudja.
- A hozzászóláshoz be kell jelentkezni
Totálisan offtopik, de a
$ sudo echo /bin/ipython3 >> /etc/shells
sor garantáltan rossz, mert a futó shelled előbb akarja megcsinálni az átirányítást, mint hogy root jogot kapnál. Szóval takard el azt a két kacsacsőröt.
/OT
- A hozzászóláshoz be kell jelentkezni
echo /bin/ipython3|sudo tee /etc/shells
A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!
- A hozzászóláshoz be kell jelentkezni
tee -a
Mint append.
When you tear out a man's tongue, you are not proving him a liar, you're only telling the world that you fear what he might say. -George R.R. Martin
- A hozzászóláshoz be kell jelentkezni
Köszi, átírva.
- A hozzászóláshoz be kell jelentkezni
Én erre gondoltam, de nyilván van pár módszer, például az is, ahogyan végül módosítottad.
$ sudo echo /bin/ipython3 '>>' /etc/shells
- A hozzászóláshoz be kell jelentkezni
Egy megjegyzés azok számára, akik nem otthonosak a Linuxon: az IPython "!"-prefixált parancsaihoz nem szükséges a @hg2ecz által említett shell-csere, ezek akkor is működnek, ha csak "simán" elindítjuk az IPython-t. Windows-on természetesen a wines parancsokat adhatjuk ki hasonlóan, például:
!powershell -command Format-Hex -Path fájlnév
Az op.rendszertől függetlenül használható pl. a %cd és a %pwd stb. (lásd a többit a helpben, az IPythonban: %magic)
- A hozzászóláshoz be kell jelentkezni
Sőt fordítva is igaz. Ha a shell ipython és bash-t akarsz, akkor
In [1]: import os
In [2]: os.system("/bin/bash")
- A hozzászóláshoz be kell jelentkezni
Na, erre nem gondoltam. Ám ez megy így is:
[1]: !/bin/bash
:-)
- A hozzászóláshoz be kell jelentkezni
érdekes, hogy a 4-esnél az "$a"-t nem bash associative array-ra fordítja hanem valami furcsa json-de-nem-is-json formátumra (curly bracket van de double quote nincs). értem én hogy nem lehet minden python tipust bash tipusra alakítani veszteség nélkül, de mit csinál olyan python változóval amit json-ra se lehet alakítani?
- A hozzászóláshoz be kell jelentkezni
- A hozzászóláshoz be kell jelentkezni
jó, hát ez eléggé tetszett elsőre, de kiderült hogy gagyi...
In [2]: a = json.loads('{"a":"b","c":1}')
In [3]: !echo "$a"
{u'a': u'b', u'c': 1}
In [4]: !echo '${a}'
${ua: ub, uc: 1}
In [5]: !echo '$a'
{ua: ub, uc: 1}
most akkor exportálja a változókat hogy a shell environ-ból kapja vagy csak egy vak behelyettesítést csinál anelkül hogy teljes értékűen perse-olná a shell command line-t.
úgy látszik, hogy a második, ami viszont nem várt következményeket okozhat…
szanitizált minden python változódat, mielőtt átadnád a shellnek!
In [14]: q="1'2"
In [16]: !echo $q
sh: 1: Syntax error: Unterminated quoted string
várj, lehet hogy nem spawn-ol minden "!"-nél egy-egy új shell-t és azért nem env-en keresztül adja át a változókat, hogy minden "!" hívásnál egyetlen folytonos shell sessionben tudjon dolgozni.
In [12]: !x=5
In [13]: !echo $x
hát nem.
- A hozzászóláshoz be kell jelentkezni
félig elnézést kérek, a fenti python2 volt.
python3 már valamivel konzisztensebb, de még mindig saját maga ügyetlenkedik a behelyettesítéssel:
In [3]: a = json.loads('{"a":"b","c":1}')
In [4]: !echo $a
{a: b, c: 1}
In [5]: !echo "$a"
{'a': 'b', 'c': 1}
# értem már, rendes json ez, csak single quote-okkal :)
In [6]: !echo '$a'
$a
# na, itt érti a single quote-okat
In [7]: q="1'2"
In [8]: !echo $q
/bin/bash: -c: sor: 0: váratlan EOF „'” helyett
/bin/bash: -c: sor: 1: szintaktikai hiba: váratlan fájlvége
# itt már nem
In [9]: !echo "${a:0:5}"
# semmi...
- A hozzászóláshoz be kell jelentkezni
Anélkül, hogy értenék Pythonhoz, a beparsolt objektumból dict lesz, aminek semmi köze a JSON-hoz, csak történetesen az is kapcsoszárójeleket használ amikor stringgé alakítod. Próbáld ki, hogy az egyik property egy boolean vagy null, azoknak is más a string reprezentációja.
- A hozzászóláshoz be kell jelentkezni
Látszik, hogy a Python sokszínű struktúráit nem célszerű egyben odadobni a shell felé. Lásd:
- list .. többféle változótípussal
- dict
- tuple
- set
Viszont ha Python-ból lebontod alap típusra, és abból automatikusan vagy explicit stringe(ke)t formálsz és azt adod át argumentumok formájában, akkor a shell-nél már semmi probléma.
Továbbá ügyelni kell arra, hogy a shell string delimiter karakterei és szóköz érzékenysége miatt a megfelelő idézőjel (szimpla vagy dupla), netán escape-elve a stringben levő idézőjelet, szóközt, stb. legyen átadva a shellnek.
In [1]: import json
In [2]: a = json.loads('{"a":"b","c":1}')
In [3]: !echo $a
{a: b, c: 1}
In [4]: b = a['c']
In [5]: !echo $b
1
In [6]: q = "1'2"
In [7]: !echo "$q" # szóközt átviszi, de a stringben levő " karakterre Python-ból kell odafigyelni
1'2
In [8]: q = "1\"2" # vagy q = '1"2'
In [9]: q
Out[9]: '1"2'
In [10]: !echo "$q"
/bin/bash: -c: sor: 1: váratlan EOF „"” helyett
/bin/bash: -c: sor: 2: szintaktikai hiba: váratlan fájlvége
In [11]: q = q.replace('"', '\\"')
In [12]: q
Out[12]: '1\\"2'
In [13]: !echo "$q"
1"2
- A hozzászóláshoz be kell jelentkezni
Replace helyett ez is használható.
- A hozzászóláshoz be kell jelentkezni
igen, épp ez az ami böki a csőrömet, hogy külön figyelni kell a változó átadására.
hogy gördülékenyebben legyen python+bash integrálva én exportálnék minden változót mielőtt elindítom a bash-t és akkor nem kell a 40 féle bash-es quotation syntaxszal kontárkodni; nem kell replace-elni egyaltalán: a "!" utáni részt egy az egyben át lehet adni a bashnak.
persze ennek van hátulütője is, mert ugye így pl nem használhatsz egy PATH nevű python valtozót büntetlenül.
azt mondjuk ki lehet kötni hogy az all-caps változókat nem adja át a shellnek, mondván hogy az ilyen env var-ok nagyban befolyasolhatják a bash működését.
aztán ha még eggyel tovább megyek, a bash lehetne olyan kedves és API-ként kiajánlhatná a tokenizáló logikáját, akkor nem kéne minden shellt hívó programmnak jól-rosszul magának implementálnia.
hány shell injection vulnerability született olyanok miatt hogy a hívó program validálni akarta hogy miket ad át egy parancs paramétereinek, aztán shell-en keresztül hívta és a shell máshogy értelmezte a -c utáni stringet.
- A hozzászóláshoz be kell jelentkezni