Boş kabuk değişkenleri kullanırken hata verin


22

Bazen $PROJECT_HOME/*projedeki tüm dosyaları silmek için kullanırım . Ortam değişkeni PROJECT_HOMEayarlanmadığında (yaptığım suve yeni kullanıcının bu ortam değişkeni ayarlanmadığı için), tüm dosyaları kök klasörden silmeye başlar. Bu kıyamettir.

bashKabukta tanımsız bir ortam değişkeni kullandığımda hata atmaya nasıl yapılandırabilirim ?


5
set -une istersen onu yapacağım.
cuonglm

cevap olarak yapabilir misin?

2
Tabii ki varslarınızı boş karakter dizileri ile başlatamazsınız. [ -z "$VAR" ]başlatılmamış VARda çalışır . Başlatma, sadece istenmeyen davranışları göstermek içindi - Amacım, varslarınız boş dizgilere ne şekilde olursa olsun başlatılırlarsa ve rm -r "$PROJECT_HOME"/*yanlışlıkla güvenerek set -uçalışırsanız, "kıyamet" davranışını elde edersiniz. IHMO, bilgisayarınızın tüm içeriğini korumak söz konusu olduğunda, üzgün olmaktan daha güvenli olmak daha iyidir. set -ugüvenli değil.
PSkocik

3
"O cok uzun"? Tehlikeli işlemleri manuel olarak gerçekleştirmek için uygun bir yol aramamalısınız. Bunun yerine, istediğiniz şeyi yapmak için bir işlev, diğer ad veya komut dosyası oluşturmalısınız; Bu durumda, @ PSkocik'in önerdiği komuttan bir takma ad vermek güvenli ve rahat olacaktır.
Kyle Strand

1
Kullanıcı ayarlarsa ne olur PROJECT_HOME=/etc? Felaketi önlemek için sadece boş bir değerin kontrol edilmesi yeterli değildir. Kök olarak çalışırken güvenilmeyen kullanıcıların değişkenlerini kullanmamalısınız.
Barmar

Yanıtlar:


27

POSIX kabuğunda kullanabilirsiniz set -u komutunu :

#!/bin/sh

set -u
: "${UNSET_VAR}"

veya kullanma Parametre Genişletme :

: "${UNSET_VAR?Unset variable}"

Senin durumunda, sette boş ama başarısız olan değişkenleri de kullanmak :?yerine kullanmalısın ?:

rm -rf -- "${PROJECT_HOME:?PROJECT_HOME empty or unset}"/*

17
[ -z "$PROJECT_HOME" ] || rm -r "$PROJECT_HOME"/*

Bu aynı zamanda olayı da yakalayacaktır. PROJECT_HOME olan set başka bir şey içermiyor.

Örnek:

1) Bu, sisteminizde silebileceğiniz hemen hemen her şeyi siler (içindeki dotfiles'i engeller /(genellikle hiçbiri yoktur)):

set -u
PROJECT_HOME=
rm -r "$PROJECT_HOME"/*

2) Bu hiçbir şey yapmaz:

PROJECT_HOME=
[ -z "$PROJECT_HOME" ] || rm -r "$PROJECT_HOME"/* 

Projenizi tamamen evden kaldırmak ve yeniden yaratmak başka bir seçenek olabilir (eğer nokta dosyalarından kurtulmak istiyorsanız):

#no apocalyptic threats in this scenario
rm -r "$PROJECT_HOME"
mkdir "$_" 

1
-zTamam, ancak $PROJECT_HOMEbir dizin olması gerekiyordu, belki -ddaha iyi olurdu. [[ -d $PROJECT_HOME ]] && rm -r "$PROJECT_HOME".
kojiro

2
PROJECT_HOME bir yörüngeye ayarlı değilse, bu muhtemelen bir yazım hatası nedeniyle katastrofik olmayan bir hatadır. -dÇek o hatayı gizlemek olacaktır. Bunun üzerine giderse çok daha iyi olacak rmve rmyüksek sesle bu konuda şikayet ediyor.
PSkocik

2
PROJECT_HOME ayarlanırsa, ancak isim bir dizin değilse [[ -d $PROJECT_HOME ]] && rm -r "$PROJECT_HOME", sessizce hiçbir şey yapmaz. Ancak [[ -z $PROJECT_HOME ]] || rm -r "$PROJECT_HOME", dizin olmayan bir dosya olsa bile "$ PROJECT_HOME" u sessizce siler. Hata mesajı almak asla sorun olmaz:if [[ -d $PROJECT_HOME ]]; then rm -r "$PROJECT_HOME"; else printf '%s is not a directory\n' "$PROJECT_HOME" >&2; fi
kojiro

1
Şimdi "yanlışlıkla" ayarlandı PROJECT_HOME="/."...
Hagen von Eitzen

1
@HagenvonEitzen PROJECT_HOME kök olarak ayarlanmışsa, PROJECT_HOME'u boşaltan prosedür kök boşalır. Beklenen ve tamamen makul davranış budur. Ve o son noktaya bile ihtiyacın yok.
PSkocik

0

Bunu yapmanın başka bir yolu:

rm -r "${somevar:-/tmp/or_this_if_somevar_is_empty}"/*

Birçok değişken ikamesi vardır, yukarıdakilerden biri "somevar" boş olduğundadır (ve bu durumda silmeye çalışır /tmp/or_this_if_somevar_is_empty/*)


1
Veya: rm -fr ${ENV_VAR:?suitably caustic message here}/*ama yine de değer basit testler yıkmak için birçok yolu vardır belirterek, kök dizinine bağlanır etmediğini değerinde denetimi olabilir: //, /.., /usr/who/../.., ...
Jonathan Leffler

Evet. Parametre genişletme kullanacaksanız , gerçekten hata
Digital Trauma
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.