JC, लोकप्रिय कमांडलाइन टूल्स के आउटपुट को JSON में बदलता है
(github.com/kellyjonbrazil)- JC कई CLI टूल्स, फ़ाइल फ़ॉर्मैट्स और सामान्य strings के आउटपुट को JSON में बदलता है, ताकि scripts में उन्हें आसानी से parse किया जा सके
- यह pipe input लेता है और
STDOUTपर JSON output देता है, साथ हीjc dig example.comजैसी magic syntax भी सपोर्ट करता है - डिफ़ॉल्ट output parser-विशिष्ट strict schema का उपयोग करता है और numbers,
null, boolean, तथा अतिरिक्त semantic fields को convert करता है;-rयाraw=Trueसे pre-processing से पहले के raw JSON तक पहुँचा जा सकता है - इसे Python library के रूप में भी इस्तेमाल किया जा सकता है, जहाँ JSON की जगह Python dictionary, dictionary list, या lazy iterable के रूप में result मिल सकता है
- बड़े और लंबे समय तक चलने वाले pipelines के लिए यह JSON Lines/NDJSON output देने वाले streaming parsers,
--slurp,--meta-out, local parser plugins, और platform compatibility warnings को suppress करने के options देता है
JC क्या करता है
- JC(JSON Convert) कई CLI टूल्स, फ़ाइल फ़ॉर्मैट्स और सामान्य strings के आउटपुट को JSON में बदलता है
- बदले हुए output को
jqयाjelloजैसे टूल्स के साथ pipe करके आगे process किया जा सकता है - उदाहरण के तौर पर
dig example.com | jc --digdigके output को JSON array में बदलता है, और फिरjq -r '.[].answer[].data'से सिर्फ IP addresses निकाले जा सकते हैं - यही काम
jc dig example.com | jq -r '.[].answer[].data'जैसी magic syntax से भी किया जा सकता है
CLI और Python library का उपयोग
- बेसिक CLI उपयोग pipe input लेकर JSON representation output करने का है
COMMAND | jc [SLICE] [OPTIONS] PARSERcat FILE | jc [SLICE] [OPTIONS] PARSERecho STRING | jc [SLICE] [OPTIONS] PARSER
- magic syntax में
jc [SLICE] [OPTIONS] COMMANDयाjc [SLICE] [OPTIONS] /proc/<path-to-procfile>फ़ॉर्म में command या/procफ़ाइल के आगेjcलगाया जाता है- command alias और shell builtin सपोर्ट नहीं होते
- Python में इसे
jc.parse('dig', cmd_output)की तरह call किया जाता है- return value JSON string नहीं, बल्कि Python dictionary, dictionary list, या streaming parser का lazy iterable हो सकता है
- Python package docs
help('jc'),help('jc.lib'), या online docs में देखे जा सकते हैं
Output representation और schema
- डिफ़ॉल्ट representation parser-विशिष्ट strict schema का उपयोग करता है
- पहचाने गए numbers को JSON
intयाfloatvalues में बदला जाता है - पहचानी गई
Nonevalues को JSONnullमें बदला जाता है - पहचानी गई boolean values भी convert की जाती हैं
- कुछ parsers अतिरिक्त semantic fields जोड़ते हैं
- पहचाने गए numbers को JSON
- raw pre-processed JSON तक CLI के
-roption या Python library केparse(..., raw=True)से पहुँचा जा सकता है - हर parser का schema parser list के पास दिए गए docs links में देखा जा सकता है
- JSON output डिफ़ॉल्ट रूप से compact format में होता है, और
-poption से pretty format इस्तेमाल किया जा सकता है -yया--yaml-outoption से YAML output भी दिया जा सकता है
Supported parsers और उपयोग के उदाहरण
- सपोर्टेड targets में CLI commands, फ़ाइल फ़ॉर्मैट्स और string parsers शामिल हैं
- README की parser list में
dig,ls,ping,ps,netstat,ifconfig,csv,xml,yaml,/etc/hosts,/etc/passwd,/proc/,systemctl,git log,jwt,url,semver, औरx509से संबंधित फ़ाइलें शामिल हैं - example outputs दिखाते हैं कि अलग-अलग inputs को JSON structures में कैसे बदला जाता है
arpoutput को address, hardware type, MAC address, और interface fields में बदला जाता है- CSV फ़ाइल को header को key मानने वाले object array में बदला जाता है
/etc/hostsको IP और hostname arrays में बदला जाता हैifconfigको interface name, MTU, IPv4/IPv6 addresses, packet·byte counters आदि वाले object में बदला जाता हैpingको packet send/receive counts, loss rate, round-trip time, और response list वाले object में बदला जाता है
- Ansible में इसे
community.generalcollection के filter plugin के रूप में इस्तेमाल किया जा सकता है
Installation
jcको कई तरीकों से install किया जा सकता हैpip3 install jc- OS package repositories
- GitHub Releases के architecture-specific binaries
- OS package installation examples में ये शामिल हैं
- Debian/Ubuntu:
apt-get install jc - Fedora:
dnf install jc - openSUSE:
zypper install jc - Arch:
pacman -S jc - macOS:
brew install jc - FreeBSD: ports के जरिए installation
- Ansible filter plugin:
ansible-galaxy collection install community.general - FortiSOAR connector: FortiSOAR Connector Marketplace से installation
- Debian/Ubuntu:
मुख्य options
-a/--about:jcऔर parser information को JSON या YAML में output करता है-d/--debug: parsing समस्या होने पर trace messages output करता है, और-ddअधिक detailed debugging देता है-h/--help: help output करता है, औरjc -h --parser_nameसे parser docs देखी जा सकती हैं-M/--meta-out: timestamp, parser name, magic command, magic command exit code जैसी metadata को output में जोड़ता है-q/--quiet: parser warning messages को suppress करता है, और-qqstreaming parser errors को ignore करता है-s/--slurp: multi-line input को array में समेटता है-u/--unbuffer: output buffering को disable करता है-B/--bash-comp,-Z/--zsh-comp: Bash या Zsh completion script generate करता है
Slice और Slurp
- Slice Python slicing जैसी
START:STOPsyntax से input lines के सिर्फ एक हिस्से को process करता है - उदाहरण के लिए, header और footer वाली table में
jc 1:-1 --asciitableयाjc 1:4 --asciitableसे बीच का data ही JSON में बदला जा सकता है - positive और empty slice सबसे memory-efficient होते हैं, जबकि negative slice ज्यादा memory इस्तेमाल करते हैं
- Slurp single-line input लेने वाले string parsers में कई items को एक साथ array के रूप में output करने की सुविधा है
- उदाहरण: हर line में एक IP address वाली फ़ाइल को
jc --slurp --ip-addressसे process किया जा सकता है
- उदाहरण: हर line में एक IP address वाली फ़ाइल को
/procmagic syntax कई files चुने जाने पर अपने-आप slurp सपोर्ट करती है- कई
/procfiles convert करने पर हर result object में_filefield जुड़ता है, ताकि पता चल सके कि वह किस file से आया है
- कई
--meta-outऔर slurp को साथ इस्तेमाल करने परresultarray और_jc_metaobject में wrapped structure output होता है
Exit codes और metadata
jcके अंदर होने वाली fatal errors exit code100बनाती हैं, अन्यथा यह0return करता है- magic syntax इस्तेमाल होने पर
jc, parse किए जाने वाले program का exit code save करता है और उसेjcexit code में जोड़ता है- अगर
ifconfigका1औरjcका0है, तो combined exit code1होगा - अगर
ifconfigका0औरjcका100है, तो combined exit code100होगा - अगर दोनों में error है, तो combined exit code
101होगा
- अगर
- magic syntax में
--meta-outया-Mइस्तेमाल करने पर_jc_metaobject में magic command information और exit code शामिल होते हैं
Colors और environment variables
JC_COLORSenvironment variable से key name, keyword, number, और string colors तय किए जा सकते हैं- इसका format
JC_COLORS=<keyname_color>,<keyword_color>,<number_color>,<string_color>है - color values में
black,red,green,yellow,blue,magenta,cyan,gray,brightblack,brightred,brightgreen,brightyellow,brightblue,brightmagenta,brightcyan,white,defaultमें से कोई एक हो सकता है
- इसका format
NO_COLORenvironment variable सेट करने पर color output disable हो जाता है-Coption,NO_COLORenvironment variable और-moption से ऊपर प्राथमिकता लेकर color output force करता है
Streaming parsers
- ज़्यादातर parsers पूरा
STDINmemory में पढ़कर parse करते हैं और फिर JSON document को serialized form में output करते हैं - कुछ streaming parsers input मिलते ही line-by-line process करते हैं और JSON Lines या NDJSON में output देते हैं
- उदाहरण:
ls-s,ping-s - इससे
ls -lR /जैसे बड़े command outputs की memory usage बहुत कम हो सकती है, और कुछ मामलों में processing तेज भी हो सकती है
- उदाहरण:
- streaming parsers को magic syntax के साथ इस्तेमाल नहीं किया जा सकता
- लंबे समय तक चलने वाले pipelines में parsing error से pipe न टूटे, इसके लिए
-qqया Python मेंignore_exceptions=Trueइस्तेमाल किया जा सकता है- सफल lines में
_jc_meta.success: trueशामिल होता है - असफल lines में
_jc_meta.success: false,error, औरlinefields शामिल होते हैं
- सफल lines में
- अगर pipes के बीच operating system buffering की वजह से output देर से दिखे, तो
-uसे unbuffered output इस्तेमाल किया जा सकता है- हालांकि बड़े data streams में unbuffered output धीमा हो सकता है
- Python में streaming parsers iterable input लेते हैं और iterable object return करते हैं, जिससे lazy processing संभव होती है
Parser plugins
- local parser plugin को app data directory के
jc/jcparsersfolder में रखा जा सकता है- Linux/unix:
$HOME/.local/share/jc/jcparsers - macOS:
$HOME/Library/Application Support/jc/jcparsers - Windows:
$LOCALAPPDATA\\jc\\jc\\jcparsers
- Linux/unix:
- plugin standard Python module files होते हैं
jc/parsers/foo.pyयाjc/parsers/foo_s.pyको template की तरह इस्तेमाल किया जा सकता है- plugin filename एक valid Python module name होना चाहिए, letter से शुरू होना चाहिए, और उसमें सिर्फ alphanumeric characters और underscore होने चाहिए
- local plugins डिफ़ॉल्ट parsers को override कर सकते हैं
Locale, timezone, और compatibility
- सबसे अच्छे results के लिए
LC_ALLकोCयाen_US.UTF-8पर set करने की सलाह दी जाती है - कुछ पुराने systems में
Clocale UTF-8 encoding सपोर्ट नहीं करता, इसलिए UTF-8 output ASCII और\\uescape sequences में downgrade हो सकता है - कुछ parsers calculated epoch timestamp fields जोड़ते हैं
- अगर field name में
_utcsuffix नहीं है, तो उसे local timezone पर आधारित naive timestamp माना जाता है - अगर command output text में UTC timezone detect हो जाए, तो timezone-aware timestamp बनाया जाता है और key name में
_utcsuffix जुड़ता है - UTC के अलावा अन्य timezones aware timestamp के रूप में supported नहीं हैं
- अगर field name में
- कुछ parsers platform-specific outputs convert करते हैं, इसलिए unsupported platform पर चलाने पर warning दिखाई जाती है
- unsupported platform पर भी दूसरे systems के output files parse किए जा सकते हैं; इस स्थिति में
-qया Python केquiet=Trueसे warnings suppress की जा सकती हैं - tested platforms में Centos 7.7, Ubuntu 18.04/20.04, Fedora32, macOS 10.11.6/10.14.6, NixOS, FreeBSD12, Windows 10, Windows 2016 Server, और Windows 2019 Server शामिल हैं
1 टिप्पणियां
Hacker News की रायें
FreeBSD में यह समस्या कुछ हद तक libxo से हल होती है:
$ ps --libxo=json | jqकी तरह structured output मिल सकता हैयह परफेक्ट नहीं है;
lssupport था लेकिन किसी कारण हटा दिया गया, और सभी utilities भी इसे support नहीं करतींjcकई command parsers देने वाला एक बेहतरीन अस्थायी हल लगता है, लेकिन इसकी सीमा यह है कि यह ऐसे text output को parse करता है जिसे मूल रूप से parsing के लिए design नहीं किया गया थाअच्छा होगा अगर utilities एक common flag के साथ structured output दें; PowerShell जैसा default Unix/Linux के लिए ज़्यादा हो सकता है, लेकिन सिर्फ standard
--jsonflag भी बड़ी प्रगति होगीhttps://wiki.freebsd.org/LibXo
https://reviews.freebsd.org/D13959
मेरी समझ से यह सिर्फ structured data pass नहीं करता, बल्कि pipeline में opaque objects बहने देता है और पिछली stage पर लौटकर methods भी call किए जा सकते हैं: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_methods?view=powershell-7.4
jc,libxoजैसे wrappers और https://www.nushell.sh/ जैसी experimental shells भी अच्छी हैं, लेकिन ये executable methods वाले objects से ज़्यादा data transfer पर ध्यान देती हैंstructured data अभी भी Unix-जैसा लगता है, और अगर सचमुच objects चाहिए हों तो शायद Python या Ruby चलाने का समय है
shell चाहे जितनी शानदार हो और उसमें programming features हों, यह जानना ज़रूरी है कि shell script से कब किसी proper programming language पर जाना चाहिए
jcको अब तक इस भूमिका को भरने वाले tool के रूप में पेश किया गया है, और ऐसा लगता है कि Unix tools में-j/--jsonsupport व्यापक होने तक इसे एक stepping stone के रूप में सोचा गया हैhttps://blog.kellybrazil.com/2019/11/26/bringing-the-unix-philosophy-to-the-21st-century/
/procके नीचे की entries unstructured text files नहीं बल्कि JSON data लौटाती हैंइससे भी ज़्यादा structured समाधान यह हो सकता है कि ELF से data structures export किए जा सकें, फिर उन data structures को terminal output के लिए serialize किया जाए, और उसके बाद user अपनी पसंद के JSON, YAML जैसे formats में उन्हें output या process करे
सही utility याद नहीं, शायद
iostatथा, और वह JSON output lines को string interpolation से format कर रहा था, जिससे कुछ flag combinations में output पूरी तरह टूट जाता थाअब स्थिति बेहतर है या नहीं, पता नहीं, लेकिन spacing options होने पर मुझे JSON lines जैसे किसी format की उम्मीद थी
usability के लिहाज़ से PowerShell और kubectl libxo से कहीं आगे लगते हैं
https://github.com/Juniper/libxo
https://libxo.readthedocs.io/en/latest/
आइडिया सच में बहुत अच्छा है, लेकिन maintenance के बारे में सोचकर चिंता होती है
versions, command flags के हिसाब से output में बदलाव वगैरह देखें तो यह maintenance hell जैसा लगता है; असली इस्तेमाल में कुछ cases में यह अच्छा चलेगा, लेकिन basic cases से आगे जाते ही इसका नया-पन जल्दी खत्म हो जाएगा
ऊपर से tool options में
--का उपयोग भी बहुत अच्छा नहीं लगताअगर हर नए parser के लिए नया flag चाहिए, तो help या man page हज़ारों lines की हो सकती है
अगर कोई utility अपना JSON export support करने लगे, तो बाद में यह tool उसी feature को delegate कर सकता है
jc lsकी तरह command के आगेjcलगाकर भी इस्तेमाल किया जा सकता है--cmdparameter conversion से पहले data को process करने देता है, इसलिए यह उल्टा अच्छा idea हैउदाहरण के लिए, conversion से पहले आप list को
grepकरना चाह सकते हैंmaintenance के नज़रिए से भी, अगर base Unix commands का output बहुत बदल जाए तो यह tool ही नहीं बल्कि अनगिनत scripts भी टूटेंगी, इसलिए दूसरे binaries के updates की वजह से यह शायद उतनी बार नहीं टूटेगा जितना लगता है
एक अच्छी तरह maintain किया गया shared parser bundle जगह-जगह बिखरे ad-hoc output parsers से बेहतर है, लेकिन अगर मैं कोई complex काम करने के लिए सीधे JSON output चाहता हूँ, तो parsing खुद समस्या में और इज़ाफ़ा न करे, यही चाहूँगा
इसे आराम से इस्तेमाल करने के लिए शायद मुझे जिन चीज़ों का उपयोग करना है, उन सबके लिए अतिरिक्त test cases के PR भेजने पड़ेंगे
वैसे भी वे tests मुझे खुद लिखने ही पड़ते
लोगों को जिन tools की parsing जानकारी चाहिए, वह submit करनी होगी, और users को भी उसे आसानी से up-to-date बनाए रखना होगा
Nushell का तरीका अलग है, लेकिन ज़्यादातर वही लक्ष्य हासिल करता है: shell commands का structured data
आम तौर पर shell खुद ही यह भूमिका निभाता है
http://www.nushell.sh/
from jsonऑपरेशन है, इसलिए यह JC के साथ वास्तव में अच्छी तरह मेल खाता हैमैंने पहले Nushell की कुछ अच्छी features दिखाने वाला एक वीडियो रिकॉर्ड किया था, और लगभग 19 मिनट पर
jcके साथ इसे जोड़ने की बात की है: https://www.youtube.com/watch?v=KF5dtxVsn1Eमैं एक script लिखना चाह रहा था जो किसी खास pattern से मेल खाने वाली directories में files को देखे और जिनकी modification time एक-दूसरे से 10 मिनट के भीतर हो उन्हें हटा दे; तभी याद आया कि Nushell ऐसे कामों के लिए अच्छा है
थोड़ी देर इस्तेमाल किया तो आखिरकार बात समझ आ गई, और अब मैं इसका प्रशंसक हो गया हूँ
unstructured data भी अगर records की list जैसी शक्ल में बदलकर प्रोसेस किया जा सके तो बहुत ताकतवर हो जाता है
एक मायने में यह शानदार है कि files हर जगह हैं; यही Unix का वादा है, और Plan 9 में यह और भी आगे बढ़ा हुआ रूप लेता है
लेकिन unstructured files होना, या हर file का अलग format होना, उतना ही बाधा भी बनता है
सिर्फ
awkजैसी चीज़ों से एक nginx log file पार्स करने की कोशिश भी झंझट भरी हो सकती हैबड़ी कमियों में से एक यह है कि Linux user space में बड़े पैमाने पर system rewrite या design change लागू करना मुश्किल है
मुझे ज़्यादा समझदार shell चाहिए, मुझे files भी पसंद हैं, और बगल में
awkकी किताब भी रखी है, लेकिन अब लगता है कि data parsing में गंभीर सुधार की ज़रूरत हैजैसे programs खुद तय कर लेते हैं कि color output render करना है या नहीं, वैसे ही अगर वे structured output भेजना है या नहीं यह भी तय कर सकें तो अच्छा होगा
किसी भी text UI को API की तरह इस्तेमाल किया जा सकता है, इसलिए इंसानों के लिए पढ़ने लायक text को प्राथमिकता मिलती है
इसीलिए shell scripting कुछ हद तक third-party browser extension बनाने जैसी लगती है
आप देखते हैं, अंदाज़ा लगाते हैं, फिर उसी अंदाज़े के आधार पर जल्दी-जल्दी parser जोड़ते हैं और उम्मीद करते हैं कि सब चल जाए
machine-readable content के लिए तीसरा standard output होना अच्छा रहेगा
terminal इसे default रूप से प्रिंट न करे, लेकिन pipe करने पर यही output pipe हो; यह JSONL हो; और manual page contract को स्पष्ट करे
तब standard output इंसानों के लिए रखा जा सकता है, और parsing एक ऐसा काम होगा जिसे इस समझ के साथ किया जाएगा कि वह संभव तो है, लेकिन नाज़ुक है
बेशक यह पूरी तरह backward compatibility तोड़ने वाला विचार है, और अगर अवास्तविक तरीके से CLI को नींव से दोबारा गढ़कर modernize करना हो, तो बदलने की मेरी सूची बहुत लंबी है
सुधार हासिल करना भी वाकई बहुत मुश्किल है, और Lennart जैसा कोई व्यक्ति जब दशकों पुराने जमे हुए कचरे को हटाने की कोशिश करता है, तो तुरंत ड्रामा शुरू हो जाता है
JSON भी अभी परफेक्ट नहीं है
JSON ठीक-ठाक अच्छा idea है, लेकिन अगर इसे सही ढंग से करना हो तो ऐसा format चाहिए जो data types जैसी चीज़ों को व्यक्त कर सके
यह PowerShell के अधिक करीब होना चाहिए, ताकि numbers को numbers की तरह संभाला जा सके और
$a - $bसे dates का अंतर निकालने जैसी शानदार चीज़ें की जा सकेंअच्छा होगा अगर GNU coreutils में यह हो जाए
समस्या यह है कि वह .NET और objects में बहुत गहराई से जड़ा हुआ है, इसलिए किसी भी platform पर मौजूदा native commands के साथ उसका integration बहुत कठिन हो जाता है
क्योंकि वे मूल रूप से पहले से वही काम कर रही हैं
फिर भी लगता है कि अंतिम लक्ष्य यही होगा कि ऊपर की layers के tools इसकी value समझें और खुद structured output देना शुरू करें
बढ़िया
मैं sensible JSON output को support करने वाले CLI tools का ज़ोरदार समर्थक हूँ, और https://github.com/WireGuard/wireguard-tools/blob/master/contrib/json/wg-json जैसी चीज़ें और PowerShell का
|ConvertTo-Jsonadmin/monitoring automation का बड़ा हिस्सा हैंलेकिन यहाँ sensible शब्द बहुत काम कर रहा है, और हक़ीक़त तो हक़ीक़त है
LSI/Broadcom StorCLI में command के अंत में
Jजोड़ने वाले तरीके, या PowerShell के COM-hiding wrappers जैसी चीज़ें तकनीकी रूप से JSON तो हैं, लेकिन नतीजा इतना बेहूदा जटिल या बेकार होता है कि अंत में फिर “चलो plain-text output पर regex चला लेते हैं” जैसे जुगाड़ पर लौटना पड़ता हैफिर भी मैं इसे ज़रूर देखूँगा
अगर पहला उदाहरण
digoutput parsing उन चीज़ों का प्रतिनिधि है जिन्हें स्थिर तरीके से किया जा सकता है, तो यह काफ़ी दिलचस्प होगामेरे हिसाब से
jc dig example.comही default syntax होना चाहिएdig example.com | jc --digमें output को parse करने के लिए पिछले command के flags और parameters का बाद में अंदाज़ा लगाना पड़ता हैयह कि हर output एक object है, PowerShell की उन बातों में से एक है जो मुझे सबसे ज़्यादा पसंद हैं
जब भी मुझे bash scripts लिखनी पड़ती हैं, इसकी कमी महसूस होती है
जिसने इसे maintain करने की ज़िम्मेदारी ली है, उसे सलाम
aws s3 ls | jc --aws=1.2.3जैसी चीज़ तो एक दुःस्वप्न होगीइससे Linux या Unix के
fileprogram और उसे maintain करने वाले नायकों की याद आती हैpluginsजैसी चीज़ें load की जा सकें, जैसे उन्हें अलग shell commands के रूप में रखा जाए, तो maintenance effort का कुछ हिस्सा plugin authors को सौंपा जा सकता हैयह जानने की जिज्ञासा है कि कौन-कौन से modern Unix command-line tools
--jsonoption स्वीकार करते हैंऐसी जानकारी इस repository में जोड़ना भी उपयोगी हो सकता है
ifconfigका modern replacementipJSON support करता हैlldpctlभी support करता हैAnsible सिस्टम की details को
factsनाम के JSON के रूप में देता है, और automation को उसी का उपयोग करने के लिए डिज़ाइन किया गया हैlsblkमें--jsonflag है और यह काफ़ी जानकारी दे सकता हैlsblk --json --output-allआज़मा सकते हैंजब scripts को सिस्टम की disks और partitions inspect करनी हों, तब यह बहुत उपयोगी है
-T jsonflag के साथ इसे support करता हैदिलचस्प project है
लेकिन मुझे लगा था कि पहले चरण के parser के रूप में textfsm जैसी किसी चीज़ का उपयोग होगा
textfsm का उपयोग network equipment के CLI output को parse करने में काफ़ी होता है
https://github.com/google/textfsm