2013-03-22 23 views
7

Bash'da yeni bir satır sembolü içeren bir değişken yazdırmakla biraz kafam karıştı. Bu çalışıyorYeni hat ile bash printf

var="Age:\n20\ncolor:\nred" 
echo -e $var 
Age: 
20 
color: 
red 

ama birçok insan seçenekleriyle o yankı not portable ve it is better to use printf olduğunu söylüyorlar.

Hiç prinf kullanmıyorum. Yankı komutunu vermek için elkitaplarına göre:

Ancak bu, iç değişkeni ayrıştırmaz. kılavuzları genellikle bu örneği vardır:

printf "Surname: %s\nName: %s\n" "$SURNAME" "$LASTNAME" 

Ama benim böyle değil ve bakış benim açımdan rahat değil kullanmak.

printf "$ var \ n"

taşınabilir mi: Ben sadece bu kullanabileceği yazarak öğrendim? Daha sonra bir mail komutuna $ var geçecek olursam, yeni satır sonları kaydeder mi?

printf "$var\n" | mail -s subj [email protected] 
+0

printf' 'ile sorun bu dahili bir kabuk (deneme ve ksh93), fakat diğerleri harici bir yöntem üzerinde bir kabuk olmasıdır (sh, ksh88, CSH) . Eski kabuklarda 'printf' kullanıldığında, programı kaç kez kullandığınıza bağlı olarak yavaşlayabilirsiniz. – cdarke

cevap

16

printf 'ın %b biçim belirteci özellikle echo -e yerine alacaktı (aslında varsayılan. -e argümanların özel yorumlanması için çağrıda echo için XSI uzatma belirtilen asla ve POSIX tarafından engellendi.), ve $'...' arasındaki birkaç fark ve printf biçimindeki biçim dizgisi bağımsız değişkeni de dahil olmak üzere hemen hemen her şekilde aynıdır.

$ (var='Age:\n20\ncolor:\nred'; printf '%b\n' "$var") 
Age: 
20 
color: 
red 

Genellikle program tam değerini kontrol sürece biçim dizesine değişkenleri genişleyen kaçınmalıdır ve özellikle bir biçim dizesi olması amaçlanmıştır. Özellikle son örneğiniz, Bash'de printf'un -v seçeneği nedeniyle oldukça tehlikeli olma potansiyeline sahiptir.

# Bad! 
var='-v_[$(echo "oops, arbitrary code execution" >&2)0]' 
printf "$var" foo 

Genellikle özel bir taşınabilirlik gereksinimi olmadığı sürece %b önlemek için iyi bir uygulamadır. Kaçak kodları değişmez veri yerine bir değişkende saklamak, kod ve verilerin ayrılması ilkelerini ihlal eder. Bunun iyi olduğu bağlamlar vardır, ancak POSIX'in bir sonraki sürümü için belirtilen $'...' teklifini kullanarak değeri atamak genellikle daha iyidir ve Bash ve çoğu ksh çeşidinde uzun zamandır mevcuttur.

x=$'foo\nbar'; printf '%s\n' "$x" # Good 
x=(foo bar); printf '%s\n' "${x[@]}" # Also good (depending on the goal) 
x='foo\nbar'; printf '%b\n' "$x"  # Ok, especially for compatibility 
x='foo\nbar'; printf -- "$x"   # Avoid if possible, without specific reason 
+0

Detaylı cevap için teşekkür ederiz. – idobr

+0

@ormaaj: Daha önce POSIX'in bir sonraki sürümüne eklenecek bir özellikten bahsettim (siz?); Bunun halka açık bir taslağı var mı? Sadece merak. – chepner

+0

@chepner Taslak özellikler aboneleri listelemek için kullanılabilir. 2008 TC1 halihazırda tamamlanmış durumda ve şu an herhangi bir zamanda olmalıydı, ancak [bu] (http://austingroupbugs.net/view.php?id=249) (ve diğer "özellik" değişiklikleri) issue 7. Liste arşivlerini [gmane] (http: //dir.gmane.org/gmane.comp.standards.posix.austin.general) veya hata izleyicisini arayın. Teoride, eğer doğru araçlara sahipseniz, hata takipçisi diffs 'den gelen şeylerin mevcut durumunu oluşturabilirsiniz (bunu denemedim). – ormaaj