! $ Komut dosyasında kullanılamaz mı?


11

Sadece bunun neden çalışmadığını merak ediyorum

#!/bin/bash 

ls /bin
ls !$

ls /binİki kez koşmayı bekliyorum , ancak ikincisi !$yorumlanmadığı için hataları arttırıyor

Bir şey mi kaçırdım, yoksa !$yalnızca komut satırında mı çalıştım ?

man bash(Mac'ta) içinde ilgili kısmı bulamadım


9
Bir çözüm olmasına rağmen, bu gerçekten bir senaryoda bunu başarmak için en iyi yoldur? geçmiş etkileşimli olmayan bir şekilde çalıştırdığınızda varsayılan olarak devre dışıdır - uzun bir komut dosyası .bash_history dosyasına spam gönderir. Bunu sormaya değmez demiyordum, ama bunu bir senaryoda kullanmayı düşünüyorsanız, bu gerçekten en iyi yol mu?
flungo

Yanıtlar:


26

Tarih ve tarih genleşme zaman kabuk çalıştırmak olmayan etkileşimli varsayılan olarak devre dışıdır.

Gerekenler:

#!/bin/bash 

set -o history
set -o histexpand

ls /bin
ls !$

veya:

SHELLOPTS=history:histexpand bash script.sh

script.shçalıştırılabilecek tüm bash örneklerini etkiler .


9
SHELLOPTS konusunda dikkatli olursanız, bunun bashçalışmasını etkiler script.sh, ancak sonunda çalışabilecek diğer tüm bashörnekleri de script.sh(diğer bashkomut dosyaları gibi ...) etkiler .
Stéphane Chazelas

Ve bu olmaz herhangi etkileyen diğer bash Senaryonu çalıştırır örneği.
Blacklight

@ StéphaneChazelas'ın yorumu düzenlenmişse bu cevabın iyileşeceğini düşünüyorum.
Oliphaunt - Monica

7

Yapmak mantıklı şey,

ls /bin
ls $_

veya

set ls /bin
$*
$*

veya

c='ls /bin'
$c
$c

Uyarılar: Bunların her birinin bazı tuzaklarla geldiğini hatırlamakta fayda var. $ _ Çözümü yalnızca son tek bağımsız değişkeni yakalar: böylece ls foo bar$ _ değerini sadece içeren içerir bar. Kullanarak bir set(bağımsız değişkenler geçersiz kılar $1, $2vs.). Ve bunların hepsi yazılı olarak çalışacaktır, ancak daha karmaşık komutlara (kaçış ve boşlukların önemli olduğu yerlerde) genelleştirildiğinde, bazı zorluklarla karşılaşabilirsiniz. Örneğin: ls 'foo bar'(tek yol adı bağımsız değişkeni iki veya daha fazla boşluk veya başka bir boşluk karakteri foo bariçerdiğinde ) bu örneklerin hiçbirinde doğru davranmayacaktır. Bu durumları aşmak için uygun bir kaçış (muhtemelen bir komutla birleştirilmiş ) veya yerine kullanmak gerekebilir.eval"$@"$*


1
Taşınabilir olan ve etkileşimli kullanımı kolaylaştırmayı amaçlayan bir bashism'i kötüye kullanmayan yanıt için +1. (Bir kenara, bash'ın varsayılan kurulumdaki ünlem işaretlerini etkileşimli olarak genişletme arzusu, diğer kabukların bir kullanıcısı olarak mantıksız bulduğum bir şeydir ve üretken çünkü bazı karmaşık kabuk komutları yapmaya çalışırken her zaman beni rahatsız ediyor).
mtraceur

Şu anda yazıldığı halde, acemi kabuk betiklerinin daha karmaşık komutlara genelleştirmeye çalışırken muhtemelen sahip olacağı sorunlar nedeniyle +1 vermekte tereddüt ettim. En azından olası tuzakları açıklayan bir uyarı paragrafı eklemek için bir düzenleme önerdim.
mtraceur

@mtraceur: taşınabilir değil, sadece bash, zsh, ksh olarak çalışır (iki komut aynı satırda değilse). Dash içinde çalış, sadece etkileşimli olduğunda
mksh

@cuongim: Üzgünüm, belki de dikkatsizce geneldim. Yol $_taşınabilir değil, haklısın. setYaklaşım etkileşimli olmayan çizgi çalışır ve birlikte ${1+"$@"}hayal meyal hatırlıyorum rağmen (artı ZSH küresel takma ad) hile, genel olmalıdır setbazı (eski?) Kabukları ile mükemmel bir taşınabilir olmama bir geçmişe sahiptir. Özellikle uygun kaçış ve gerçek bir evalkomut kullanarak, bir değişken-değişken-tutma-ve-sonra-değerlendir-o yaklaşımı, bildiğim kadarıyla tamamen taşınabilir.
mtraceur
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.