Shell Scriptlerinde Komut Satırı Argümanlarını Alıntılamak

Shell scriptleri yazarken, özellikle Windows dosya yapıları ile etkileşimde bulunan WINE gibi uygulamalar için komut satırı argümanlarını doğru bir şekilde alıntılamak oldukça önemlidir. Karşılaşılan yaygın bir problem, bu argümanların hatalı bir şekilde işlenmesidir ve bu durum yolların boşluk veya özel karakterler içermesi durumunda hatalara yol açabilir. Bu yazıda, bu tür alıntı problemlerini etkili bir şekilde nasıl ele alacağımızı tartışacağız.

Problem

Bir WINE uygulamasını çalıştırmak için tasarlanmış bir shell scriptiniz olduğunu düşünün. Script, bir argüman listesi alır, Unix yollarını Windows yollarına çevirir ve ardından yürütülebilir dosyayı çağırır. Ne yazık ki, komut satırı argümanlarındaki hatalı alıntılama nedeniyle bir hata meydana gelir:

wine: cannot find ''/home/chris/.wine/drive_c/Program' 

Gözlemlenen Ana Problemler:

  1. Yol Kırpılması: Yürütülebilir dosyanın yolu, tek tırnak içinde olmasına rağmen ilk boşlukta kesiliyor.
  2. Ters Eğik Çizgi Yorumu: ’t’ harfi ile takip edilen bir ters eğik çizgi (\t), bir literal string olarak değil, bir sekme karakteri olarak yorumlanıyor.

Alıntı Problemini Anlamak

Bu sorunlar, shell’in komut yer değişimlerinde alıntıları ve özel karakterleri nasıl yorumladığından kaynaklanmaktadır. İşte bu sorunların nedenleri:

  • Argümanlar shell’e geçirildiğinde, herhangi bir boşluk, doğru bir şekilde alıntılanmadığı takdirde komutun parçalanmasına sebep olabilir.
  • Dize olarak genişletilmiş değişkenler, kaçış karakterleri içerebilir ve bunların istenmeyen dönüşümlere yol açmamak için dikkatle ele alınması gerekir.

Örneğin, kaçış dizileri içeren bir değişkeni eko yaptığınızda, bu diziler yanlış yorumlanabilir. Bu, aşağıdaki gibi görünebilir:

Y='y\ty'
Z="z${Y}z"
echo $Z   # Çıktı: zy	 yz (zy  yz değil)

Bu tür bir davranış, hata ayıklama zorluklarına ve scriptlerde beklenmedik sonuçlara yol açabilir.

Çözüm

Bu alıntılama sorunlarını, özellikle shell script örneğimizde çözmek için yerleşik eval komutunu kullanabiliriz. Bu komut, sağlanan argümanları yeniden değerlendirir ve yürütmeden önce komut dizesinin doğru bir şekilde ayrıştırılmasını sağlar.

Adım Adım Düzeltme

  1. Scriptin Son Satırını Değiştirin: Komutu doğrudan yürütmek yerine, eval içine sarın:

    eval "$CMD"
    
  2. eval Kullanımının Avantajları:

    • Yollarında Boşluklar: Bunu boşluk içeren yolların (örneğin, Program Files) doğru bir şekilde işlenmesini sağlamak için kullanabilirsiniz çünkü mutlak alıntı içindeki tüm dizeyi tek bir komut olarak değerlendirir.
    • Kaçış İşleme: eval kullanmak, kaçış dizilerinin uygun bir şekilde işlenmesini sağlamaya yardımcı olabilir ve \t gibi istenmeyen karakter dönüşümleri riskini azaltır.
  3. Test Etme: Bu ayarlamaları yaptıktan sonra, scriptinizi boşluklar ve kaçış karakterleri içeren çeşitli girdilerle test edin ve her şeyin beklendiği gibi çalıştığından emin olun.

Nihai Script Örneği

Gözden geçirilmiş shell scriptiniz şu şekilde görünebilir:

#! /bin/sh

if [ "${1+set}" != "set" ]
then 
  echo "Kullanım; winewrap EXEC [ARGS...]"
  exit 1
fi

EXEC="$1"
shift

ARGS=""

for p in "$@"; do
  if [ -e "$p" ]; then
    p=$(winepath -w "$p")
  fi
  ARGS="$ARGS '$p'"
done

CMD="wine '$EXEC' $ARGS"
echo $CMD
eval "$CMD"

Sonuç

Shell scriptlerinde komut satırı argümanlarını alıntılamak, özellikle WINE gibi karmaşık uygulama yollarıyla çalışırken kritik bir beceridir. eval kullanarak, boşluk ve kaçış karakteri yanlış yorumlamalarına ilişkin yaygın hataların üstesinden gelebilir ve scriptlerinizin sorunsuz ve verimli çalışmasını sağlayabilirsiniz.

Scriptlerinizle deneme yapmaktan çekinmeyin ve daha fazla içgörü ya da sorularınızı aşağıdaki yorumlarda paylaşın!