Script shell untuk membuat file jika tidak ada?

19

Saya perlu membuat skrip shell yang memeriksa keberadaan file dan jika tidak ada, buat dan pindah ke perintah berikutnya, atau hanya pindah ke perintah berikutnya. Apa yang saya miliki tidak melakukan itu.

#!/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 ...

Kembali adalah

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

Tidak tahu apa yang harus dilakukan. Setiap tempat pencarian Google membawa saya menunjukkan sesuatu yang berbeda.

jrw
sumber
6
Masukkan kode Anda ke shellcheck.net dan tinjau saran yang dibuatnya
roaima
12
Apa alasan Anda tidak bisa hanya touchfile dan melewati persyaratan?
kirkpatt
Jawaban lain di bawah ini mengatasi kesalahan sintaks (tidak ada spasi di antara [dan !), tetapi mungkin membantu untuk menunjukkan di sini bahwa [ini adalah perintah aktual di Unix. Perintah Unix membutuhkan spasi kosong antara nama perintah dan argumennya. Ya, itu juga Bash bawaan , tetapi ada juga biner di /usr/bin/[sebagian besar sistem.
TheDudeAbides

Jawaban:

43

Solusi yang mungkin lebih sederhana, tidak perlu melakukan tes eksplisit, cukup gunakan:

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

Jika Anda tidak ingin waktu "modifikasi" yang sudah file.txtada diubah touch, Anda dapat menggunakan touch -a /Scripts/file.txtuntuk touchhanya mengubah waktu "akses" dan "perubahan".

xenoid
sumber
1
Jika Anda tidak peduli dengan mtime, Anda bisa menggunakannya >>/Scripts/file.txt. Ini akan membuka file untuk ditambahkan dan membuatnya jika tidak ada.
kojiro
29

Anda mendapatkan kesalahan karena tidak ada ruang di antara [dan !namun ada juga beberapa kekurangan dalam kode Anda. Pertama, Anda memeriksa apakah file tersebut tidak ada, dan jika tidak, Anda tidak melakukan apa-apa. Jika file TIDAK ADA Anda membuat direktori (tetapi tidak melakukan apa pun untuk membuat file).

Anda juga tidak perlu operasi nol, Anda harus dapat melakukan:

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

[command2]

Ini memeriksa jika /Scripts/file.txttidak ada itu akan membuat /Scriptsdirektori dan file.txtfile. Anda juga dapat memeriksa keberadaan direktori secara terpisah jika diinginkan. Selain itu perhatikan saya menggunakan -ebukan -fkarena Anda diminta hanya untuk memeriksa keberadaan file yang -eakan dilakukan di mana -fmemeriksa bahwa itu adalah "file biasa" http://tldp.org/LDP/abs/html/fto. html

Jesse_b
sumber
Terima kasih @roaima, saya telah memperbarui jawaban saya dengan saran Anda.
Jesse_b
apa file tidak ada tetapi direktori tidak?
Semut
3
@Ant: mkdir -p: buat semua direktori yang diperlukan, tanpa mengeluh jika sudah ada. mis: mkdir / home / user1 / tmp: akan membuat hierarki ini, terlepas dari fakta the / home, atau / home / user1, direktori sudah ada sebelumnya. touch juga hanya akan memperbarui waktu file yang ada, atau membuat yang baru jika tidak ada file. Seseorang bahkan dapat menghilangkan bagian if ... then, karena cukup ok untuk hanya meluncurkan 2 perintah itu, jika Anda ingin memastikan direktori tersebut ada dan file itu ada di dalamnya.
Olivier Dulac
Saya melihat! Terima kasih atas klarifikasi :)
Ant
11

Untuk mulai dengan, skrip shell bukan skrip bash , jadi mari kita buat kode Anda lebih umum:

#!/bin/sh

Setiap sistem Posix harus memiliki file itu; bash sangat opsional.

Tidak perlu menguji apakah direktori itu ada, cukup

dir=/Scripts
mkdir -p $dir

Untuk membuat file jika tidak ada,

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

Atau jika Anda lebih suka,

filename=$dir/file.txt
if [ ! -f $filename ]
then
    touch $filename
fi
James K. Lowden
sumber
6

Anda memiliki kesalahan sintaksis. Anda memerlukan spasi sebelum dan sesudah [dan ].

DopeGhoti
sumber
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"

Di atas mengasumsikan bahwa tidak ada "trik" seperti membuat direktori yang disebut /Scripts/file.txt(yang bisa menjadi cara memaksa skrip untuk selalu memasukkan cabang if). Jika "file" adalah direktori, tes -f akan gagal dan perintah sentuh tidak akan mengubah apa pun.

LSerni
sumber
0

pendekatan saya

#!/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"

keluaran

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

.

selamat tinggal
sumber
1
Anda tidak memeriksa apakah file itu ada
PiedPiper
@piepdpiper yang dia lakukan, ini tersirat dalam touchdanmkdir -p
xenoid
id yang sama dengan tampilan yang lebih mirip: D = / boot / bork; F = fnord; mkdir -p "$ D" && {touch "$ D / $ F" && echo "membuat $ D / $ F OK"; } || {echo "tidak dapat membuat dir '$ D'"; }
jmullee