İlk önce bir test tabanı yapacağım - 5 dosya ve bir klasör:
touch file1 file2 file3 file4 file5
mkdir folder
Sonra bir test komutu çalıştıracağım. -v
Seçenek belirtir Ben kabuk yürüttüğü için basılacak her komutu istediğiniz stderr
. -x
Ben basılmış aynı istiyoruz seçenek belirtir stderr
- ama yapılmasını isterim sonra komut değerlendirilir ama önce kabuk çalıştırır.
sh -cxv 'echo mv *'
ÇIKTI
echo mv *
+ echo mv file1 file2 file3 file4 file5 folder
mv file1 file2 file3 file4 file5 folder
Yani, kabuğu beslediğim komutu görüyorsunuz echo mv *
ve kabuğun genişletildikten sonra yürüttüğü komut tüm bu dosyalar ve klasörler tarafından takip ediliyor.*
echo mv
Varsayılan olarak, kabuk aşağıdaki gibi globları genişletir :
sh -cxv 'echo file[1-5]'
ÇIKTI
echo file[1-5]
+ echo file1 file2 file3 file4 file5
file1 file2 file3 file4 file5
Bu, set [+-]f
glob işlevinin bir sonucudur :
sh -cxvf 'echo file[1-5]'
ÇIKTI
echo file[1-5]
+ echo 'file[1-5]'
file[1-5]
Bu nedenle mv *
, kabuk gibi varsayılan seçeneklerle yapılandırılmış bir kabukta bir komut çalıştırdığınızda , *
kelimeye, geçerli dizindeki tüm dosyaların yerel ayarlarına göre sıralanmış bir argüman listesi genişler . Bu sistem çağrısını yapar exec(ve)
için mv
(aslında) eklenen bu argüman listesi ile. Böylece mv
tüm argümanlar kabuk onları götürür ve sıralar gibi alır. Yapıyor yanı sıra strace
bu etkileri görmek için, tekrar hata ayıklama gibi dışarı kullanabilirsiniz:
sh -s -- mv * <<\SCRIPT
sed -n l /proc/$$/cmdline
echo "$@"
SCRIPT
ÇIKTI
sh\000-s\000--\000mv\000file1\000file2\000file3\000file4\000file5\000folder\
\000$
mv file1 file2 file3 file4 file5 folder
Ve taşınabilir olarak:
( PS4= IFS=/; set -x mv *; : "/$*/" ) 2>&1
ÇIKTI
: /mv/file1/file2/file3/file4/file5/folder/
Temel olarak, kabuk yürütür mv
dizinin içeriği ile (isimler ile başlayan ile dosyaları / klasörleri dahil bu boş değilse, değil .
) onun argüman listesi olarak. mv
aynı şekilde - POSIX ikiden fazla argümanla çağrılır eğer bir dizin olarak nihai argümanı yorumlamak belirtilen olduğu ln
olduğu (aslında, onlar fonksiyonu altında yatan inanılmaz derecede benzer araçlar olduğunuz için) .
Yeterince yeter echo
:
sh -cxv 'mv *' ; ls
ÇIKTI
mv *
+ mv file1 file2 file3 file4 file5 folder
folder/
Tüm dosyalar son argümana taşındı - çünkü bu bir klasör. Peki ya klasör değilse?
sh -cxv 'cd *; mv *'; ls . *
ÇIKTI
cd *; mv *
+ cd folder
+ mv file1 file2 file3 file4 file5
mv: target ‘file5’ is not a directory
.:
folder/
folder:
file1 file2 file3 file4 file5
POSIX’in mv
bu durumda nasıl davranması gerektiğini şöyle ifade eder:
mv [-if] source_file target_file
mv [-if] source_file... target_dir
İlk özet biçiminde, mv
yardımcı program source_file operand tarafından adlandırılan dosyayı target_file tarafından belirtilen hedefe taşıyacaktır . Bu ilk özet formu, son işlenen varolan bir dizine isim vermediğinde ve varolan bir dizine işaret eden sembolik bir bağ olmadığında varsayılır. Bu durumda, source_file dizin dışı bir dosyayı isimlendirir ve target_file izleyen bir /slash
karakterle bitiyorsa , mv
bunu bir hata olarak kabul eder ve hiçbir source_file işleneni işlenmez.
İkinci özet formunda, mv
source_file operand adıyla belirtilen her dosyayı target_dir operand tarafından adlandırılan varolan dizindeki bir hedef dosyaya veya hedef_dir'in varolan bir dizine atıfta bulunan sembolik bir bağ olması durumunda başvuruda bulunmalıdır . Her source_file için hedef yolu, hedef dizinin bitiştirilmesi, hedef bir bitmediyse tek bir /slash
karakter /slash
ve source_file öğesinin son yol adı bileşeni olmalıdır . Bu ikinci form, final operand varolan bir dizini adlandırdığında varsayılır.
Yani *
genişlerse: