Kabuk betiği yoksa bir dosya oluşturmak için?


20

Bir dosyanın varlığını kontrol eden bir kabuk komut dosyası oluşturmak gerekir ve yoksa, oluşturur ve sonraki komut için devam eder, ya da sadece sonraki komut için devam eder. Sahip olduğum şey bunu yapmıyor.

#!/bin/bash

# Check for the file that gets created when the script successfully finishes.
if [! -f /Scripts/file.txt]
then
: # Do nothing. Go to the next step?
else
mkdir /Scripts # file.txt will come at the end of the script
fi

# Next command (macOS preference setting)
defaults write ...

Dönüş

line 5: [!: command not found
mkdir: /Scripts: File exists

Ne yapacağımı bilmiyorum. Google aramasının getirdiği her yer farklı bir şey olduğunu gösterir.


6
Kodunuzu shellcheck.net'e koyun ve önerileri gözden
geçirin

12
Herhangi bir nedenle sadece touchdosya ve koşul atlamak?
kirkpatt

Aşağıdaki diğer yanıtlar sözdizimi hatasını ele almaktadır ( [ve arasındaki boşluğu kaçırmaktadır !), ancak muhtemelen [Unix'te gerçek bir komut olduğunu belirtmek yararlı olacaktır . Unix komutu, komut adı ile argümanları arasında boşluk olmasını gerektirir. Evet, bir Bash yerleşkesi de var, ancak /usr/bin/[çoğu sistemde de bir ikili var .
thedudeabides

Yanıtlar:


44

Muhtemelen daha basit bir çözüm, açık testler yapmaya gerek yok, sadece kullanın:

mkdir -p /Scripts
touch /Scripts/file.txt

Varolan bir bir "değişiklik" zaman istemiyorsanız file.txttarafından değiştirilmesi touchkullanabileceğiniz touch -a /Scripts/file.txtyapmak touchsadece "erişim" ve "değişim" saatlerinizi değiştirin.


1
Eğer mtime umursamıyorsanız, kullanabilirsiniz >>/Scripts/file.txt. Bu, dosyayı ekleme için açar ve yoksa oluşturur.
kojiro

30

Hatayı alıyorsunuz çünkü arasında boşluk yok [ve !kodunuzda bazı kusurlar var. Öncelikle dosyanın mevcut olup olmadığını kontrol edersiniz ve eğer yoksa hiçbir şey yapmıyorsunuzdur. Dosya DOES ise, bir dizin oluşturursunuz (ancak dosyayı oluşturmak için hiçbir şey yapmazsınız).

Ayrıca null işleme ihtiyacınız yoktur, şunları yapmanız gerekir:

#! /bin/bash -
if [[ ! -e /Scripts/file.txt ]]; then
    mkdir -p /Scripts
    touch /Scripts/file.txt
fi

[command2]

Bu, /Scripts/file.txtyoksa /Scriptsdizin ve sonra file.txtdosyayı oluşturacak olup olmadığını kontrol eder . İsterseniz dizinin varlığını ayrıca kontrol edebilirsiniz. Buna ek olarak, sadece bir "normal dosya" olup olmadığını denetler ne yapacak bir dosya varlığını kontrol etmek istediğini -eyerine kullanıyorum dikkat -fedin http://tldp.org/LDP/abs/html/fto. html-e-f


Teşekkürler @roaima, cevabınızı önerinizle güncelledim.
Jesse_b

dosya nedir, ancak dizin nedir?
Ant

3
@Ant: mkdir -p: önceden varsa, şikayet etmeden tüm gerekli dizinleri oluşturun. örnek: mkdir / home / user1 / tmp: / home veya / home / user1 dizinlerinden önceden var olandan bağımsız olarak bu hiyerarşiyi oluşturur. touch aynı zamanda mevcut bir dosyanın saatini de güncelleyecek veya dosya yoksa yeni bir dosya oluşturacaktır. Bu dizinlerin var olduğundan ve dosyanın içinde bulunduğundan emin olmak istiyorsanız, if ... then parçasından bile kurtulabilirsiniz.
Olivier Dulac

Anlıyorum! Açıklama için teşekkürler :)
Ant

11

Başlangıç ​​olarak, kabuk komut dosyası bash komut dosyası değildir , bu yüzden kodunuzu daha genel yapalım:

#!/bin/sh

Her Posix sisteminde bu dosya bulunmalıdır; bash kesinlikle isteğe bağlıdır.

Dizinin var olup olmadığını test etmeye gerek yok, sadece

dir=/Scripts
mkdir -p $dir

Dosya yoksa, dosyayı oluşturmak için,

filename=$dir/file.txt
test -f $filename || touch $filename

Ya da isterseniz,

filename=$dir/file.txt
if [ ! -f $filename ]
then
    touch $filename
fi

6

Sözdizimsel bir hatanız var. Sen boşluk öncesinde ve sonrasında ihtiyaç [ve ].


3
#!/bin/bash

# Check for the file that gets created when the script successfully finishes.
CHECKFILE="/Scripts/file.txt"

CHECKDIR=$( dirname "$CHECKFILE" )

# The directory with the file must exist
mkdir -p "$CHECKDIR"
if [ ! -f "$CHECKFILE" ]; then
    # What to do if the file is not there
fi
touch "$CHECKFILE"

Yukarıda adı verilen bir dizin oluşturmak gibi bir "hileler" olmadığını varsayar /Scripts/file.txt(bu komut dosyasını her zaman if dalına girmeye zorlamanın bir yolu olabilir ). "Dosya" bir dizinse, -f testi başarısız olur ve touch komutu hiçbir şeyi değiştirmez.


0

benim yaklaşımım

#!/bin/sh

# input might contains spaces and other characters
FILEPATH="/tmp/some where/the file.blah"

# extract the file + dir names
FILE="`basename "${FILEPATH}"`"
DIR="`dirname "${FILEPATH}"`"

# create the dir, then the file
mkdir -p "${DIR}" && touch "${DIR}/${FILE}"

# show result
ls -l "$FILEPATH"

çıktı

  ./dofile.sh
  -rw-r--r-- 1 jmullee jmullee 0 Nov 15 21:23 /tmp/some where/the file.blah

.


1
Dosyanın var olup olmadığını kontrol
etmiyorsunuz

@piepdpiper yapar, bu belirsiz touchvemkdir -p
xenoid

daha fazla kontrol ile aynı ides şöyle: D = / boot / bork; F = fnord; mkdir -p "$ D" && {"$ D / $ F" ye dokunun && echo "$ D / $ F OK oluşturdu"; } || {echo "dir '$ D' oluşturamadı"; }
jmullee
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.