- Go फ़ाइलों को executable की तरह सीधे चलाने की एक ट्रिक का परिचय
- पहली पंक्ति में
//usr/local/go/bin/go run "$0" "$@"; exit रखें और execute permission दें, तो ./script.go से चलाया जा सकता है
- यह तरीका shebang नहीं है, बल्कि POSIX में ENOEXEC होने पर shell के /bin/sh पर fallback करने वाले व्यवहार का उपयोग करता है
- shell पहली पंक्ति को command की तरह चलाता है, और Go compiler उसे
// comment मानकर नज़रअंदाज़ कर देता है
"$0" से अपनी ही path पास की जाती है, इसलिए go run script को build और execute करता है, और $@ से arguments पास होते हैं
- Go की मज़बूत standard library और backward compatibility की गारंटी इसे scripting के लिए उपयुक्त बनाती है, और Go 1.x version इस्तेमाल करने पर script दशकों तक चल सकती है
- Python के virtual environment, pip/poetry/uv जैसी dependency management की जटिलता से बचा जा सकता है
नकली shebang कैसे काम करता है
- shebang(
#!) execve system call के ज़रिए interpreter तय करने का तरीका है, लेकिन यहाँ बताई गई तकनीक shebang नहीं है
- Go source file की पहली पंक्ति में
//usr/local/go/bin/go run "$0" "$@"; exit रखकर, उसके नीचे package main और सामान्य Go code लिखा जाता है
chmod +x script.go से execute permission देने पर इसे ./script.go की तरह चलाया जा सकता है
strace से देखने पर पता चलता है कि shell जब ./script.go को execve से चलाने की कोशिश करता है, तो kernel ENOEXEC(Exec format error) लौटाता है
- ENOEXEC मिलने पर shell fallback के तौर पर
/bin/sh का उपयोग करके उसी फ़ाइल को shell script की तरह interpret करता है
- shell में
// comment नहीं है, बल्कि root path(/) की तरह interpret होता है, इसलिए //usr/local/go/bin/go एक वैध path की तरह execute हो जाता है
- इसलिए पहली पंक्ति
//usr/local/go/bin/go run "$0" "$@"; exit shell में command की तरह execute होती है
"$0" execute की गई फ़ाइल का path देता है, इसलिए command में "$0" script.go path बन जाता है और go run उसी फ़ाइल को ढूँढकर build और execute करता है
"$@" positional arguments expansion है, जिससे ./script.go -f flag0 here are some args जैसी invocation संभव होती है
; exit न हो तो sh Go फ़ाइल को आगे भी लाइन-दर-लाइन interpret करता रहेगा और package जैसे token पर error देगा
Go scripting के लिए उपयुक्त क्यों है
- Go की backward compatibility की गारंटी इसकी मुख्य विशेषताओं में से है, इसलिए Go 1.x इस्तेमाल करने पर लिखी गई script लंबे समय तक चलती रहती है
- अच्छी तरह विकसित standard library और built-in tools (formatter, linter आदि) बिना अलग setup के मिलते हैं, जिससे script sharing और portability अधिकतम हो जाती है
- Python की तरह virtual environment या अलग-अलग package managers (pip, poetry, uv) सीखे बिना code चलाया जा सकता है
- Go ecosystem के built-in tools और IDE integration की वजह से
.pyproject या package.json के बिना भी formatter और linter डिफ़ॉल्ट रूप से इस्तेमाल किए जा सकते हैं
- अगर सिर्फ़ नया Go installed हो, तो किसी भी OS पर दशकों तक चलाया जा सकता है
दूसरी compiled languages से तुलना
- Rust में compile speed धीमी है, standard library अपेक्षाकृत कमज़ोर है, dependency का उपयोग लगभग अनिवार्य हो जाता है, और perfectness पर ज़ोर होने से development speed धीमी पड़ती है
- Java और JVM भाषाओं में पहले से JVM bytecode आधारित scripting languages मौजूद हैं, और हल्की Kotlin scripting भी एक विकल्प हो सकती है
- compiled languages में Go के पास scripting use case के लिए सबसे उपयुक्त गुण हैं
gopls formatting समस्या और समाधान
gopls comment के बाद space मांगता है (//example → // example), इसलिए नकली shebang लाइन टूट जाती है
- space आ जाने पर
// usr/local/go/bin/go बन जाता है, जिसे shell path की तरह नहीं पहचानता
- समाधान: HN thread के सुझाव के अनुसार
// की जगह /**/ block comment का उपयोग करें
- इसे
/*usr/local/go/bin/go run "$0" "$@"; exit; */ के रूप में लिखा जा सकता है
exit के बाद semicolon(;) अनिवार्य है
अभी कोई टिप्पणी नहीं है.