Just thought others might find this somewhat interesting:
This is awesome! Thanks for sharing.
I am currently messing around with some bash
for a colleague. I'll have to try PowerShell
, soon.
Isn't Racket just delightful?
#! /usr/bin/racket
#lang racket/base
(require
"help.rkt"
racket/file
racket/cmdline)
(define the-site (make-parameter #false))
(define the-host (make-parameter #false))
(define the-fqdn (make-parameter #false))
; PARSE COMMAND-LINE INPUT
(command-line
#:program "web-vulnerability-scan"
#:once-each
[("--site")
site
"A url, e.g. https://www.google.com/"
{the-site site}]
;; these seem redundant?
[("--host")
host
"A domain and top-level domain, e.g. google.com"
{the-host host}]
[("--fqdn")
fqdn
"A fully qualified domain name, e.g. www.google.com"
{the-fqdn fqdn}]
#:args ()
(unless {the-site} (error 'web-vulnerability-scan "expected a site, found none"))
(unless {the-host} (error 'web-vulnerability-scan "expected a host, found none"))
(unless {the-fqdn} (error 'web-vulnerability-scan "expected an FQDN, found none")))
(define (temp-file prefix suffix)
(path->string (make-temporary-file* prefix suffix)))
;; EXECUTE COMMANDS
(define/command (external-ip)
#:cmd curl ifconfig.me
#:res (lambda (ip _) ip))
(define/command (zapit.txt)
#:pre [(define temp (temp-file #"zapit" #".txt"))]
;--------------------------------------------
#:cmd zaproxy -cmd -zapit ,{the-site} > ,temp
#:res (lambda _ temp))
(define/command (subdomains.txt)
#:pre [(define temp (temp-file #"subdomains" #".txt"))]
;--------------------------------------
#:cmd subfinder -d ,{the-host} -o ,temp
#:res (lambda _ temp))
(define/command (take-overs.txt)
#:pre [(define temp (temp-file #"take-overs" #".txt"))]
;------------------------------------------------
#:cmd subjack -w ,subdomains.txt -v -ssl -o ,temp
#:res (lambda _ temp))
...
I was vaguely aware of this fact, but after rediscovering the Scripts chapter in the docs, it has been a breeze.
That's a great use of Racket in a shell script! Kudos!
That's so cool! I've also been trying to use Racket for managing machine learning environments on Linux recently, and I found Racket works really well for this! Here are some code from my project
(Install miniconda and manage virtual env)
#lang racket/base
(require racket/system)
(require "../common-tools/basic-commands.rkt")
(require "../utils.rkt")
(provide conda
conda-run-in
conda-create-env
conda-install-in
pip-install-in
env-exist?
install-miniconda)
(define miniconda-default-installer-url
"https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh")
(define miniconda-tuna-mirror-install-url
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-latest-Linux-x86_64.sh")
(define (conda . cmds)
(system (build-command (cons "conda" cmds))))
(define (conda-run-in env-name cmd)
(apply conda `("run" "--live-stream" "-n" ,env-name ,cmd)))
(define (conda-create-env env-name . pkgs)
(apply conda `("create" "-y" "-n" ,env-name ,@pkgs)))
(define (conda-install-in env-name . pkgs)
(apply conda `("install" "-y" "-n" ,env-name ,@pkgs)))
(define (pip-install-in env-name . pkgs)
(conda-run-in env-name
(build-command `("python" "-m" "pip" "install" ,@pkgs))))
(define (env-exist? env-name)
(conda "list" "--name" env-name))
(define (install-miniconda
#:install-from [install-from 'default])
;; steps from <https://docs.anaconda.com/miniconda/install/#quick-command-line-install>
(mkdir-p "~/miniconda3")
(let ([installer-url (cond ['tuna miniconda-tuna-mirror-install-url]
[else miniconda-default-installer-url])])
(wget installer-url "~/miniconda3/" "miniconda.sh"))
(bash "~/miniconda3/miniconda.sh" "-b" "-u" "-p" "~/miniconda3")
(rm-rf "~/miniconda3/miniconda.sh")
(conda "init" "--all"))
(Install JAX)
#lang racket/base
(require "../venv-tools/miniconda.rkt")
(require "../utils.rkt")
(provide create-jax-env
install-jax-optimize-set-in)
(define (create-jax-env env-name #:gpu [gpu #t])
(conda-create-env env-name "python=3.11")
(pip-install-in env-name
(if gpu
(qotof "jax[cuda12]")
"jax")))
(define (install-jax-optimize-set-in env-name)
(pip-install-in env-name "jaxopt" "optax"))
(Download and compile llama.cpp, a LLM runtime)
#lang racket/base
(require "../common-tools/basic-commands.rkt")
(require "../common-tools/git.rkt")
(require "../compile-tools/cmake.rkt")
(require "../proxy/proxy.rkt")
(define llama-cpp-default-repo "https://github.com/ggerganov/llama.cpp")
(define (download-compile-llama-cpp workdir
#:cuda [cuda #t]
#:clone-with-proxy [clone-with-proxy #f])
(mkdir-p workdir)
(apt-get-install "git" "cmake")
(define llama-cpp-dir (build-path workdir "llama-cpp"))
(if clone-with-proxy
(with-proxy (git-clone llama-cpp-default-repo llama-cpp-dir))
(git-clone llama-cpp-default-repo llama-cpp-dir))
(let ([llama-cpp-build-path (build-path llama-cpp-dir "build")])
(cmake "-B" (path->string llama-cpp-build-path)
"-S" (path->string llama-cpp-dir)
(if cuda "-DGGML_CUDA=ON" ""))
(cmake "--build" (path->string llama-cpp-build-path)
"--config" "Release"
"-j" "$(nproc)")))
I'll also say that in general shell scripts are a great way to keep a skill sharp. I used practice F# by writing shell scripts for work in it.
No one cares about shell scripts you build for yourself so it's an excellent way to practice a language that's not part of the day job. When people ask me about how they can practice some language beyond C#/Java/JS that's usually my answer--write your shell scripts with it if you can.
Great day to have eyes !