Bir bash betiğinde yalnızca geçerli çalışma dizini adını veya daha da iyisi bir terminal komutunu nasıl alırım?
pwdgeçerli çalışma dizininin tam yolunu verir, örneğin /opt/local/binama sadece istiyorumbin
Bir bash betiğinde yalnızca geçerli çalışma dizini adını veya daha da iyisi bir terminal komutunu nasıl alırım?
pwdgeçerli çalışma dizininin tam yolunu verir, örneğin /opt/local/binama sadece istiyorumbin
Yanıtlar:
Basename gerekmiyor ve özellikle de bir subshell çalışan pwd'ye gerek yok ( ekstra ve pahalı bir çatal operasyonu ekliyor ); kabuk bunu parametre genişletme kullanarak dahili olarak yapabilir :
result=${PWD##*/} # to assign to a variable
printf '%s\n' "${PWD##*/}" # to print to stdout
# ...more robust than echo for unusual names
# (consider a directory named -e or -n)
printf '%q\n' "${PWD##*/}" # to print to stdout, quoted for use as shell input
# ...useful to make hidden characters readable.
Bu tekniği başka durumlarda uyguluyorsanız ( PWDdizin adını taşıyan başka bir değişken değil , bazı değişkenler), sondaki eğik çizgileri kırpmanız gerekebileceğini unutmayın. Aşağıdakiler, birden fazla sondaki eğik çizgi ile bile çalışmak için bash'ın extglob desteğini kullanır :
dirname=/path/to/somewhere//
shopt -s extglob # enable +(...) glob syntax
result=${dirname%%+(/)} # trim however many trailing slashes exist
result=${result##*/} # remove everything before the last / that still remains
printf '%s\n' "$result"
Alternatif olarak extglob:
dirname="/path/to/somewhere//"
result="${dirname%"${dirname##*[!/]}"}" # extglob-free multi-trailing-/ trim
result="${result##*/}" # remove everything before the last /
$PWDyerleşik bir bash değişkeninin adıdır; tüm yerleşik değişken adları tamamen büyük harflidir (bunları her zaman en az bir küçük harf içermesi gereken yerel değişkenlerden ayırmak için). result=${PWD#*/}does not etmek değerlendirmek /full/path/to/directory; bunun yerine, yalnızca ilk öğeyi çıkarır path/to/directory; iki #karakter kullanmak , deseni olabildiğince çok karakterle eşleştirerek açgözlü eşleşmeyi sağlar. Daha fazla bilgi için cevaba bağlı parametre genişletme sayfasını okuyun.
pwdher zaman değeriyle aynı olmadığını unutmayın . Bu, özellikle mantıksal yerine fiziksel yolun kaydedilmesinin, eğer kullanıldığında, otomatik sayacın kullanmakta olduğu dizini kendiliğinden çıkarmasına izin verecek bir yol üreteceği otomatik numaralandırılmış dizinlerin işlenmesi konusunda kötü olur. $PWDcd-o physical
shve cshsiz bütün okumuştuk çalışmak için geri tuşunu istiyorsa ve sttyadam sayfası ve biz sevdim!"
basenameProgramı kullanın . Davanız için:
% basename "$PWD"
bin
basenameprogramın amacı değil mi? Alıntıları kaçırmanın yanı sıra bu cevapta yanlış olan ne?
basenamegerçekten doğru şeyi yapmıyor harici bir program olmakla birlikte, çalışan herhangi bir şey partisi yüzünden harici program dışı-box yapabileceği tek yerleşik işlevlerini saçma kullanılarak, (performans etkisini ödemeden fork(), execve(), wait()için, vs) sebep yok.
basenameburadaki itirazlarım geçerli değildirname , çünkü dirnameişlevsel ${PWD##*/}olmayan - eğik çizgi olmayan bir dizeyi dönüştürmek .. Bu nedenle, dirnameharici bir araç olarak kullanılırken performans yükü vardır, aynı zamanda bunu telafi etmeye yardımcı olan işlevselliğe de sahiptir.
functionAnahtar kelime, standart sözdizimine herhangi bir değer katmadan POSIX ile uyumsuzdur ve tırnak işaretleri boşluk içeren dizin adlarında hatalar oluşturur. wdexec() { "./$(basename "$PWD")"; }tercih edilebilir bir alternatif olabilir.
basenamekullanım daha az "verimli". Ancak , geliştirici verimliliği açısından muhtemelen daha verimlidir, çünkü çirkin bash sözdizimine kıyasla hatırlanması kolaydır. Eğer hatırlarsanız, devam edin. Aksi takdirde, aynı şekilde basenameçalışır. Herkes bir bash betiğinin "performansını" geliştirmek ve daha verimli hale getirmek zorunda mıydı?
$ echo "${PWD##*/}"
echo "${PWD##*/}".
name=${PWD##*/}olsaydı, doğru name=$(echo "${PWD##*/}")olur ve yanlış olur (gereksiz verimsiz anlamda).
Pwd ve basename kombinasyonunu kullanabilirsiniz. Örneğin
#!/bin/bash
CURRENT=`pwd`
BASENAME=`basename "$CURRENT"`
echo "$BASENAME"
exit;
Seçilen cevabı seviyorum (Charles Duffy), ancak işaretlenmiş bir direkte iseniz ve hedef dir ismini istiyorsanız dikkatli olun. Ne yazık ki tek bir parametre genişletme ifadesinde yapılabileceğini sanmıyorum, belki yanılıyorum. Bu çalışmalı:
target_PWD=$(readlink -f .)
echo ${target_PWD##*/}
Bunu görmek için bir deneme:
cd foo
ln -s . bar
echo ${PWD##*/}
raporlar "çubuk"
Bir yolun önde gelen dizinlerini göstermek için (/ usr / bin / dirname öğesinin fork-exec işlemine gerek kalmadan):
echo ${target_PWD%/*}
Bu, örneğin foo / bar / baz -> foo / bar'ı dönüştürür
readlink -fbir GNU uzantısıdır ve bu nedenle BSD'lerde (OS X dahil) mevcut değildir.
echo "$PWD" | sed 's!.*/!!'
Bourne kabuğu kullanıyorsanız veya ${PWD##*/}kullanılamıyorsa.
${PWD##*/}POSIX sh - her modern / bin / sh (çizgi, kül vb. Dahil) bunu destekler; yeni bir kutuda gerçek Bourne vurmak için, hafif eski bir Solaris sisteminde olmanız gerekir. Bunun ötesinde - echo "$PWD"; tırnak işaretlerini bırakmak hatalara yol açar (dizin adında boşluklar, joker karakterler vb. varsa).
Şaşırtıcı bir şekilde, hiç kimse sadece yerleşik bash komutlarını kullanan bu alternatiften bahsetmedi:
i="$IFS";IFS='/';set -f;p=($PWD);set +f;IFS="$i";echo "${p[-1]}"
Ek bir bonus olarak, ana dizinin adını aşağıdakilerle kolayca elde edebilirsiniz:
[ "${#p[@]}" -gt 1 ] && echo "${p[-2]}"
Bunlar Bash 4.3-alfa veya daha yenisi üzerinde çalışır.
kullanın:
basename "$PWD"
VEYA
IFS=/
var=($PWD)
echo ${var[-1]}
Dahili Dosya Adı Ayırıcısını (IFS) tekrar boşluğa çevirin.
IFS=
IFS'den sonra bir boşluk var.
basename $(pwd)
veya
echo "$(basename $(pwd))"
pwdaktarılmadan önce dize bölünmüş ve glob genişletilmiş basename.
basename "$(pwd)"- bu sadece göre çok verimsiz olsa basename "$PWD", hangi kendisi bir parametre açılımı kullanılarak yerine çağırarak kıyasla verimsiz basenamehiç.
Orada benim gibi jokeyleri bulmak için:
find $PWD -maxdepth 0 -printf "%f\n"
$PWDiçin "$PWD"olarak değiştirin .
bunu genellikle sh betiklerinde kullanırım
SCRIPTSRC=`readlink -f "$0" || echo "$0"`
RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
echo "Running from ${RUN_PATH}"
...
cd ${RUN_PATH}/subfolder
bunu otomatikleştirmek için kullanabilirsiniz ...
Regex ile grep'in altında da çalışıyor,
>pwd | grep -o "\w*-*$"
Sadece kullan:
pwd | xargs basename
veya
basename "`pwd`"
xargsDizin adları değişmez yeni satırlar veya alıntı karakterler içerdiğinde ve ikinci formülasyon pwdkomutu çağırdığında formül yetersiz ve buggy yerleşik bir değişken genişletme yoluyla aynı sonucu almak yerine, bir alt kabukta.
Bash istemi bölgesinde yalnızca geçerli dizini görmek istiyorsanız, .bashrcdosyayı düzenleyebilirsiniz ~. Değişim \wiçin \Wdoğrultusunda:
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
Çalıştır source ~/.bashrcve yalnızca bilgi istemi bölgesinde dizin adını görüntüler.
Ref: /superuser/60555/show-only-current-directory-name-not-full-path-on-bash-prompt
gbasenameGNU coreutils'in bir parçası olan kullanmayı tercih ederim .
basenameorada deniyor . Yalnızca gbasenameMacOS ve diğer platformlarda denir , aksi takdirde GNU olmayan bir temel adla birlikte gönderilir.
Aşağıdaki komutlar, geçerli çalışma dizininizi bash komut dosyasında yazdırmanıza neden olur.
pushd .
CURRENT_DIR="`cd $1; pwd`"
popd
echo $CURRENT_DIR
$1geçerli çalışma dizinini içerecek şekilde olmasını sağladığımızdan emin değilim . (2) pushdve popdburada hiçbir amaca hizmet etmez, çünkü backticks içindeki herhangi bir şey bir alt kabukta yapılır - bu nedenle başlangıçta üst kabuğun dizinini etkileyemez. (3) "$(cd "$1"; pwd)"Boşluklu dizin adlarına karşı kullanmak hem daha okunabilir hem de daha dayanıklı olur.