24 puan yazan GN⁺ 2025-10-23 | 2 yorum | WhatsApp'ta paylaş
  • 10 yıldan uzun süredir dotfiles bakımını yaparken yazılan çeşitli shell betikleri arasından en sık kullanılanlar tanıtılıyor
  • Pano, dosya yönetimi, internet, metin işleme, REPL başlatıcıları, tarih/saat, AV, süreçler, hızlı başvuru, sistem, çeşitli başlıklarına ayrılıyor; her betik kısa bir sarmalayıcı biçiminde ve gerçek kullanım örnekleri odaklı sunuluyor
  • Betiklerin çoğu macOS ve Linux üzerinde çalışıyor; temel felsefe ise “halihazırda var olan araçların uğraştırıcı küçük pürüzlerini düzleştirmek
    • pbcopy/xclip, python3 -m http.server, yt-dlp, ffmpeg, mpv gibi standart yardımcı araçların entegrasyonu
  • En sık kullanılanlar arasında copy/pasta/pastas/cpwd, mkcd/tempe/trash/mksh, serveit/getsong/getpod/getsubs, scratch/straightquote/markdownquote, timer/boop/tunes yer alıyor

Dotfiles’ımı sürdürürken yazdığım en sık kullandığım betikler

  • 10 yılı aşkın süredir kişisel dotfiles’larımı yönetirken oluşturduğum çeşitli shell betikleri arasından, sık kullandıklarımı alanlara göre derledim
  • Her betik; amacı, kullanım sıklığı ve temsilî örnekleriyle birlikte verilerek hemen uygulanabilirlik artırılıyor
  • Ortak hedefler tekrarlayan işleri kısaltmak, platformlar arası soyutlama sağlamak ve güvenlik ile okunabilirliği artırmak

Pano ile ilgili betikler

  • copy ve pasta: sistem pano yöneticisini saran sarmalayıcılar; macOS’te pbcopy, Linux’ta xclip tabanlı
    • copy: çıktıyı panoya kopyalar
    • pasta: panodaki metni alıp çıktılar
    • Örnek: run_some_command | copy, pasta > file.txt, vim "$(pasta)", pasta | base64 --decode
  • pastas: pano durumu her değiştiğinde yeni içeriği gerçek zamanlı yazdıran bir araç
    • Kopyaladığınız tüm bağlantıları dosyaya kaydetmekte veya birden fazla bağlantıyı topluca indirmekte kullanışlı
    • Örnek: pastas > everything_i_copied.txt, pastas | wget -i -
  • cpwd: geçerli dizin yolunu panoya kopyalar
    • Birden fazla terminal sekmesi arasında dizin taşırken pratiktir

Dosya yönetimi betikleri

  • mkcd foo: dizin oluşturur ve hemen içine geçer (mkdir foo && cd foo kısayolu)
  • tempe: geçici bir dizine geçer (cd "$(mktemp -d)"); sandbox ortamında geçici iş yaparken ayrıca temizlik gerektirmez
    • Örnek:
      # Download a file and extract it  
      tempe  
      wget 'https://example.com/big_file.tar.xz'  
      tar -xf big_file.tar.xz  
      # ...do something with the file...  
      
      # Write a quick throwaway script to try something out  
      tempe  
      vim foo.py  
      python3 foo.py  
      
  • trash: dosyaları çöp kutusuna taşır (macOS/Linux desteği), basit rm kullanımına kıyasla hataları önlemeye yardımcı olur
  • mksh: yeni bir shell script dosyası oluşturur, çalıştırılabilir yapar ve düzenleyicide hemen açar

İnternet ile ilgili betikler

  • serveit: yerel dizinde statik dosya sunucusu başlatır (varsayılan port 8000, Python yoksa alternatif kullanır)
  • getsong, yt-dlp ile en yüksek ses kalitesinde ses indirme işini yapar
  • getpod: videoyu podcast için uygun ses olarak alan bir sarmalayıcıdır
  • getsubs: önce resmî altyazıları, yoksa otomatik altyazıları kullanan mantıkla İngilizce altyazı çıkarır. Özetleme hattı ve yedekleme için uygundur
  • wifi off/on/toggle: sistem WiFi kontrolü; ağ sorunlarını giderirken kullanılır
  • url: URL dizgesini ayrıştırıp protokol, ana makine adı, yol, sorgu, hash gibi parçaları böler ve çıkarır

Metin işleme betikleri

  • line 10: standart girdiden belirli bir satırı yazdırır (head, tail benzeri)
  • scratch: $EDITOR $(mktemp) gibi geçici bir metin tamponunu Vim’de hızlıca açmak için; tek seferlik notlar veya küçük dönüşümler için uygun
  • straightquote: akıllı tırnakları normal (düz) tırnaklara dönüştürür; kod içindeki tırnak sorunlarını önler ve dosya boyutunu küçültür
  • markdownquote: her satırın başına > ekleyerek Markdown alıntısı oluşturur
  • length: giriş dizgesinin uzunluğunu döndürür (wc -c yerine kullanılabilir)
  • jsonformat: JSON verisini okunaklı biçimde yazdırır
  • uppered/lowered: dizgeyi büyük/küçük harfe dönüştürür
  • nato bar: giriş dizgesini NATO alfabe koduna çevirir (Bravo Alfa Romeo gibi)
  • u+ 2025: Unicode karakterinin adını ve simgesini gösterir
  • snippets foo: belirli bir kısa ifadeyi kişisel snippet sözlüğünden çağırır
    • snippet arrow bir ok → döndürür, snippet recruiter ise “not interested” gibi şablon bir mesaj verir

REPL başlatıcıları

  • Ruby’nin irb aracından ilhamla, çeşitli dillerin REPL’lerini hızlıca çalıştırır:
    • iclj: Clojure
    • ijs: Deno (yoksa Node)
    • iphp: PHP
    • ipy: Python
    • isql: SQLite (Bash içinde bellek modu)

Tarih ve saat betikleri

  • hoy: geçerli tarihi ISO biçiminde yazdırır (örnek: 2020-04-20); dosya adı öneki olarak kullanılabilir
  • timer 10m: süre sayacı (ör. 10 dakika); bitince ses ve işletim sistemi bildirimi gönderir
  • rn: date ve cal kullanarak mevcut saati ve aylık takvimi okunaklı biçimde gösterir

Ses, video ve görsel işleme

  • ocr: macOS’te görsel dosyalarından metin çıkarır (ileride genişletilmesi planlanıyor)
  • boop: son komutun başarı/başarısızlık durumuna göre sesli bildirim verir (test çalıştırmaları sonrası gibi durumlarda sezgisel)
  • sfx: belirli efekt ses dosyalarını (.ogg) çalar; boop, timer ile birlikte kullanılabilir
  • tunes: ses dosyalarını mpv ile çalar (shuffle destekli)
  • pix: fotoğrafları mpv ile görüntüler
  • radio: sevilen internet radyo istasyonları için hızlı başlatıcı
  • speak: stdin’den okunan metinden Markdown’ı kaldırıp metin-konuşma (TTS) üretir
  • shrinkvid: video dosyalarını ffmpeg ile sıkıştırır
  • removeexif: JPEG’lerden EXIF verisini siler; ileride farklı format desteği planlanıyor
  • tuivid: terminal içinde video izletir; pratik kullanımı az olsa da ilginç bir özellik

Süreç yönetimi

  • each: xargs, find ... -exec için bir alternatif; karmaşık komutları çalıştırmayı kolaylaştırır
  • running foo: belirtilen anahtar sözcüğe göre çalışan süreçleri (PID, komut vb.) bulur ve okunması kolay biçimde gösterir
  • murder: kill için bir sarmalayıcı; yumuşak sinyallerden başlayıp gerekirse zorla sonlandırmaya kadar aşamalı kapatma uygular. Program kapatırken hataları önlemeye yardımcı olur
  • waitfor $PID: belirtilen PID sonlanana kadar bekler; bu sırada uyanık kalır
  • bb my_command: komutu gerçek arka plan modunda çalıştırır; daemon gibi işler için uygundur
  • prettypath: $PATH değişkenini satır satır, kolay okunur biçimde yazdırır (debugging için yararlı)
  • tryna my_command/trynafail my_command: komut başarılı olana kadar yinele, ya da başarısız olana kadar yinele; ağ işleri dahil çeşitli otomasyonlarda kullanılabilir

Hızlı başvuru araçları

  • emoji: anahtar sözcüğe göre emoji arar ve yazdırır
  • httpstatus: tüm HTTP durum kodlarını listeler, belirli bir kodun açıklamasını gösterir
  • alphabet: İngilizce alfabenin tüm küçük ve büyük harflerini yazdırır (şaşırtıcı derecede sık kullanılıyor)

Sistem yönetimi

  • theme 0/theme 1: sistem genel temasını (koyu/açık) değiştirir; Vim, Tmux vb. ile bağlantılı çalışır
  • sleepybear: sistemi uyku moduna alır (macOS, Linux)
  • ds-destroy: .DS_Store dosyalarını özyineli olarak siler; macOS kullanıcı klasörlerini düzenlerken faydalıdır

Diğer

  • catbin foo: PATH içindeki bir dosyanın kaynak kodunu doğrudan gösterir
  • notify: işletim sistemi düzeyinde bildirim gönderir; uzun süren işler bittiğinde anında haber verir
  • uuid: sürüm 4 UUID üretir

Sonuç

  • Bu yazıda tanıtılan betikler, yazarın gerçekten sık kullandığı araçlardır
  • Kendi yazdığınız kısayol betikleri iş akışını hızlandırma, hata önleme ve üretkenliği artırma açısından çok etkilidir
  • Sizin de kendi otomasyon betiklerinizi üretip kullanmanız önerilir

2 yorum

 
GN⁺ 2025-10-23
Hacker News görüşü
  • trash a.txt b.png komutu, a.txt ve b.png dosyalarını Çöp Kutusu'na taşır; Mac ve Linux'ta desteklenir. Benim eskiden kullandığım yöntem dosyaları tek tek sırayla işliyordu; bu yüzden silme sesi her dosya için duyuluyordu ve Finder'da ⌘Z ile yalnızca son dosya geri alınabiliyordu. İyileştirilebilir ama aslında macOS'e yerleşik gelen resmi trash komutunu kullanmak daha pratik. Finder kullanılmadığı için ses ya da ⌘Z ile geri alma yok, ama daha hızlı ve “Put Back” özelliği de çalışıyor. Ayrıca JSON pretty-print için node yerine jq kullanılırsa çok daha kısa kodla çözülüyor ve güncel macOS sürümlerinde jq önceden kurulu geliyor. UUID yazdırma da benzer; v4 UUID gerektiğinde uuidgen kullanmak en güvenlisi (man sayfasına bakın)

    • Kendi yazdığınız script'ler yerine yerleşik özellikleri kullanmak çoğu zaman daha iyi. Mesela vim'de markdownquote kullanmak yerine ilk sütunu ctrl-v ile seçip i> yazıp escape'e basmak yeterli. Daha kısa ve verimli. u+ 2025 neden ñ döndürüyor merak ediyorum; çünkü gerçek Unicode değeri U+00F1. Ayrıca catbin foo, cat "$(which foo)" ile aynı şey. zsh kullanıyorsanız cat =foo daha kısa ve daha güçlü. zsh'de = sonrasında otomatik tamamlama çalıştığı için uzun komutlarda da güvenli. Ben bunu file =firefox, vim =myscript.sh gibi sık kullanıyorum

    • Yazarın uuidgen'i bilmiyor olduğunu tahmin ediyorum. Böyle bilgi ya da ayarları paylaşmanın güzel yanı, hep kör noktalarımı ortaya çıkarması; bu yüzden paylaşmak önemli

    • Python da varsayılan olarak JSON pretty-print yapabiliyor

      $ echo '{ "hello": "world" }' | python3 -m json.tool
      {
        "hello": "world"
      }
      
    • trash bilgisi için teşekkürler. Ben şimdiye kadar birden fazla dosyayı Çöp Kutusu'na göndermek için tell app \"Finder\" to move {%s} to trash biçiminde AppleScript kullanıyordum

    • rm ve trash alternatifi olarak rip de öneririm rip proje bağlantısı

  • Geliştirici hayat döngüsü gerçekten ilginç. Başta tamamen vanilla shell ortamı kullanıyorsunuz; 1-2 yıl sonra yüzlerce satırlık script ve bash alias'ı yazıyorsunuz. Şimdi 15. yılımdayım ve tam tersine mümkün olduğunca varsayılan shell'i kullanıyor, alias bile tanımlamıyor, karmaşık şeyleri Python ya da Go ile çözüyorum

    • Bu eğilim bana bir aydınlanmadan çok düpedüz tembellik gibi geliyor (aynısını yaptığım için söylüyorum). Ortamını derinlemesine özelleştiren iş arkadaşlarım sayesinde sık sık yeni araçlar öğreniyorum; yakın zamanda Linux sistemime atuin ve fzf gibi araçlar da ekledim

    • alias ve function'ları dotfile'lara yazıp sık kullanılan komutları kaydetmek/hatırlamak için kullanıyorum. Sık kullanılan araç setimi sürekli güncelliyorum ve yeni workstation'a taşımak da kolay oluyor

    • Eskiden yalnızca bir tane nix bilgisayarım varken çok özelleştirme yapmak istiyordum. Şimdi aynı anda birden fazla makine kullandığım için sadece gerekli paketleri kurup ortamı standartlaştırıyorum

    • Python ile yazılmış olanlara da hâlâ script diyorum. Bence script terimi sadece shell script ile sınırlı değil

    • Bugünlerde genç mühendislerle çalışırken onların bir sürü dotfile kullandığını görünce “ben de eskiden böyleydim, ne uğraştırıyordu” diye düşünüyorum. Artık araçları seçici kullanıyor, gereken şeye esnek biçimde uyarlıyorum. Başkalarının tarzına da saygı duyuyorum

  • HN'de böyle pratik ipuçları içeren gönderiler bulmayı gerçekten seviyorum. Diğer geliştiricilerin gerçekte nasıl çalıştığını ve benim neleri öğrenip uygulayabileceğimi merak ediyorum. İlk başta “bana lazım olmaz” diye düşünseniz bile, bir iş kolaylaştığında o işin kendisi yeni bir workflow yaratıyor. O yüzden önce deneyip uyan şeyleri bırakıyorum. Orijinal yazının tarzı da hoşuma gidiyor — gerçek kullanım sıklığını da yazmış olması gerçekten pratik. Ben basit işler için çoğu zaman tarayıcı devtools'u açıp JavaScript ile işi bitiriyorum. (Örneğin bir string'i küçük harfe çevirmek gibi)

    • Yazarın yöntemiyle benim yöntemimin harcadığı süreyi, script'i yazma/hatırlama/başvurma/taşıma maliyetini de hesaba katıp gerçek bir cost-benefit analysis yapmak ilginç olurdu

    • Bu Bash kısayol cheat sheet görseli çok yardımcı oluyor

  • line script'i yerine belirli satırları yazdırmak için sed ile daha basit yapılabilir

    sed -n 2p file
    

    bununla ikinci satır yazdırılabilir. Birden fazla satır için de

    sed -n 2,4p file
    

    kullanılabilir; bu yüzden line script'inden daha avantajlı

    • Birden fazla sed komutunu bir arada kullanmam gereken durumlar çok oluyor. O zaman ilk sed komutunu sürekli değiştirmek gerekiyor. Bazen sed öncesinde grep de gerekebiliyor; ama cat, tail, head ile parçalarsanız her işlevi modül gibi kullanmak daha esnek oluyor. Bu, her aracın tek bir iş yapmasını savunan Unix felsefesine de uyuyor
  • Sık kullandığım bazı basit script'ler var. Mesela:

    #!/usr/bin/env bash
    # ~/bin/,dehex
    
    echo "$1" | xxd -r -p
    
    #!/usr/bin/env bash
    # ~/bin/,ht
    
    highlight() {
      # renkler: 30=siyah, 31=kırmızı, 32=yeşil, ...
      escape=$(printf '\033')
      sed "s,$2,${escape}[$1m&${escape}[0m,g"
    }
    
    if [[ $# == 1 ]]; then
      highlight 31 $1
    elif [[ $# == 2 ]]; then
      highlight 31 $1 | highlight 32 $2
    elif [[ $# == 3 ]]; then
      highlight 31 $1 | highlight 32 $2 | highlight 35 $3
    elif [[ $# == 4 ]]; then
      highlight 31 $1 | highlight 32 $2 | highlight 35 $3 | highlight 36 $4
    fi
    

    Kişisel script'lerin başına , (virgül) koyuyorum; böylece hızlı geçiş yapabiliyorum. Kendi script'lerimi zaman zaman geçmiş üzerinden istatistikleyip artık kullanmadıklarımı temizlemenin değerli olduğunu düşünüyorum

  • Henüz genelleştiremedim ama unmv script'i ile epey rahat çalışıyorum

    #!/bin/sh
    if test "$#" != 2
    then
      echo 'Error: unmv must have exactly 2 arguments'
      exit 1
    fi
    exec mv "$2" "$1"
    
  • Çok iyi ipuçları var ama ben genelde standart yardımcı araçları (sed, awk, grep, xargs vb.) öğrenip kullanıyorum. Çünkü farklı sistemler arasında çalışırken kişisel script ve alias'larımın çoğu kurulu olmuyor. Standart araçlarla neredeyse her şey yapılabiliyor

    • Kesinlikle katılıyorum. Her yerde çalışabilmek için insan standartlara yöneliyor. Ama gerçekten iyi araçlar zamanla ya varsayılan kurulumda geliyor ya da apt-get ile kolay kurulur hale geliyor. Kişisel script yığını yerine iyi bakılan paketler şeklinde olmaları daha tercih edilir bence
  • En sevdiğim arşiv açma script'imi paylaşayım

    # ex - archive extractor
    # kullanım: ex <dosya>
    function ex() {
      if [ -f $1 ] ; then
      case $1 in
        *.tar.bz2) tar xjf $1 ;;
        *.tar.gz) tar xzf $1 ;;
        *.tar.xz) tar xf $1 ;;
        *.bz2) bunzip2 $1 ;;
        *.rar) unrar x $1 ;;
        *.gz) gunzip $1 ;;
        *.tar) tar xf $1 ;;
        *.tbz2) tar xjf $1 ;;
        *.tgz) tar xzf $1 ;;
        *.zip) unzip $1 ;;
        *.Z) uncompress $1;;
        *.7z) 7z x $1 ;;
        *) echo "'$1' ex() ile çıkartılamıyor" ;;
      esac
      else
        echo "'$1' geçerli bir dosya değil"
      fi
    }
    
    • Bunun sıkıştırma yapan ters counterpart'unu da yazmak istiyorum

    • Ben dtrx kullanıyorum; arşivi otomatik olarak bir klasörün içine açması çok iyi oluyor

    • Bana aunpack daha rahat geliyor

    • Gerçekten temiz bir çözüm

    • inotify ve systemd user service da eklerseniz bir seviye daha ileri gider. Bunun paket olarak sunulan sürümleri de zaten var. Kendi yaptığınız çözüm biraz kare tekerleği yeniden icat etmek gibi duruyor

  • mp4 encode etmek veya kesmek için hep kullandığım iki function var. Flag'ler sayesinde WhatsApp, mobil Discord gibi ortamlarda uyumluluk maksimum oluyor

    ffmp4() {
      input_file="$1"
      output_file="${input_file%.*}_sd.mp4"
    
      ffmpeg -i "$input_file" -c:v libx264 -crf 33 -profile:v baseline -level 3.0 -pix_fmt yuv420p -movflags faststart "$output_file"
    
      echo "Compressed video saved as: $output_file"
    }
    
    ffmp4 foo.webm  # foo_sd.mp4'e dönüştürür
    
    fftime() {
      input_file="$1"
      output_file="${input_file%.*}_cut.mp4"
      ffmpeg -i "$input_file" -c copy -ss "$2" -to "$3" "$output_file"
    
      echo "Cut video saved as: $output_file"
    }
    
    fftime foo.mp4 01:30 01:45  # foo_cut.mp4 oluşturur
    

    fftime, orijinali yeniden encode etmeden hızlı kesim yapar ama videoya göre küçük sorunlar çıkarabilir (örneğin oynatılamama gibi). Yeniden encode etmek isterseniz -c copy seçeneğini kaldırmanız yeterli

  • alias veya function oluşturup test ederken ~/.zshrc dosyasını anında yeniden yüklemek için aşağıdaki alias'ı kullanıyorum

    alias vz="vim ~/.zshrc && . ~/.zshrc"
    

    Ayrıca Mac'te docx dosyalarında grep benzeri arama için şu function'ı kullanıyorum

    docgrep() {
      mdfind "\"$@\"" -onlyin /Users/xxxx/Notes 2> >(grep --invert-match ' [UserQueryParser] ' >&2) | grep -v -e '/Inactive/' | sort
    }
    

    Bir de Mac'imdeki panoyu anonimleştirip ChatGPT ya da şirket içi Slack gibi herkese açık kanallara yapıştırmadan önce debug amaçlı şu function'ı çalıştırıyorum. Function çalışınca yeni dönüştürülmüş pano içeriğini stdout'a da yazdırdığı için gözden kaçan bir şey olup olmadığını kontrol edebiliyorum

    anonymizeclipboard() {
      my_user_id=xxxx
      account_ids="1234567890|1234567890" #regex
      corp_words="xxxx|xxxx|xxxx|xxxx|xxxx" #regex
      project_names="xxxx|xxxx|xxxx|xxxx|xxxx" # regex
      pii="xxxx|xxxx|xxxx|xxxx|xxxx|xxxx" # regex
      hostnames="xxxx|xxxx|xxxx|xxxx|xxxx|xxxx|xxxx|xxxx|xxxx" # regex
      pbpaste | sed -E -e 's/([0-9]{1,3})\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/\1.x.x.x/g' \
      -e "s/(${corp_words}|${project_names}|${my_user_id}|${pii}|${hostnames})/xxxx/g" -e "s/(${account_ids})/1234567890/g" | pbcopy
      pbpaste
    }
    alias anon=anonymizeclipboard
    
    • Bu gerçekten harika. Böyle bir durumla sık karşılaşıyorum ama doğru düzgün bir yöntem bulamadığım için hep zorlanıyordum
 
krepe90 2025-10-24

GeekNews'te yayımlanan Ask GN: Sık kullandığınız shell snippet'ları var mı? başlıklı yazı da aklıma geliyor