Shell script để tạo một tập tin nếu nó không tồn tại?


19

Tôi cần tạo một tập lệnh shell để kiểm tra sự hiện diện của tập tin và nếu nó không tồn tại, hãy tạo nó và chuyển sang lệnh tiếp theo hoặc chỉ chuyển sang lệnh tiếp theo. Những gì tôi có không làm điều đó.

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

Trả lại là

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

Không biết nên làm gì. Mỗi nơi một tìm kiếm Google mang lại cho tôi một cái gì đó khác nhau.


6
Đặt mã của bạn vào shellcheck.net và xem xét các đề xuất mà nó đưa ra
roaima

12
Bất kỳ lý do bạn không thể chỉ touchcác tập tin và bỏ qua các điều kiện?
kirkpatt

Các câu trả lời khác bên dưới giải quyết lỗi cú pháp (thiếu khoảng trắng giữa [!), nhưng có lẽ hữu ích khi chỉ ra đây [là một lệnh thực tế trên Unix. Một lệnh Unix yêu cầu một số khoảng trắng giữa tên lệnh và các đối số của nó. Vâng, đó cũng là một nội dung Bash , nhưng cũng có một hệ nhị phân /usr/bin/[trên hầu hết các hệ thống.
TheDude Abides

Câu trả lời:


43

Có thể giải pháp đơn giản hơn, không cần làm các xét nghiệm rõ ràng, chỉ cần sử dụng:

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

Nếu bạn không muốn "sửa đổi" thời gian của một hiện file.txtphải được thay đổi bằng cách touch, bạn có thể sử dụng touch -a /Scripts/file.txtđể làm cho touchchỉ thay đổi "truy cập" và "thay đổi" lần.


1
Nếu bạn không quan tâm đến thời gian, bạn có thể sử dụng >>/Scripts/file.txt. Điều này sẽ mở tệp để nối thêm và tạo nó nếu nó không tồn tại.
kojiro

29

Bạn đang gặp lỗi vì không có khoảng cách giữa [!tuy nhiên cũng có một số lỗi trong mã của bạn. Đầu tiên bạn đang kiểm tra xem tập tin không tồn tại và nếu không bạn sẽ không làm gì cả. Nếu tệp DOES tồn tại, bạn đang tạo một thư mục (nhưng không làm gì để tạo tệp).

Bạn cũng không cần thao tác null, bạn chỉ có thể thực hiện:

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

[command2]

Đây là kiểm tra nếu /Scripts/file.txtkhông tồn tại, nó sẽ tạo /Scriptsthư mục và sau đó là file.txttệp. Bạn cũng có thể kiểm tra sự tồn tại của thư mục riêng nếu bạn muốn. Ngoài ra, tôi lưu ý rằng tôi đang sử dụng -ethay vì -fnhư bạn yêu cầu chỉ đơn giản là kiểm tra sự tồn tại của tệp, đó là những gì -esẽ làm khi -fkiểm tra xem đó có phải là "tệp thông thường" http://tldp.org/LDP/abs/html/fto. html


Cảm ơn @roaima, tôi đã cập nhật câu trả lời của tôi với đề xuất của bạn.
Jesse_b

tập tin không tồn tại nhưng thư mục nào?
Kiến

3
@Ant: mkdir -p: tạo tất cả các thư mục cần thiết, mà không phàn nàn nếu đã tồn tại. ví dụ: mkdir / home / user1 / tmp: sẽ tạo ra hệ thống phân cấp này, độc lập với thực tế các thư mục / home hoặc / home / user1, tồn tại trước đó. touch cũng sẽ chỉ cập nhật thời gian của một tệp hiện có hoặc tạo một tệp mới nếu không có tệp nào tồn tại. Người ta thậm chí có thể thoát khỏi phần ... sau đó, vì việc khởi chạy 2 lệnh đó là khá ổn, nếu bạn muốn đảm bảo các thư mục đó tồn tại và tệp đó tồn tại trong đó.
Olivier Dulac

Tôi hiểu rồi! Cảm ơn bạn đã làm rõ :)
Ant

11

Để bắt đầu, shell script không phải là bash script , vì vậy hãy làm cho mã của bạn tổng quát hơn:

#!/bin/sh

Mỗi hệ thống Posix phải có tệp đó; bash là hoàn toàn tùy chọn.

Không cần kiểm tra nếu thư mục tồn tại, chỉ cần

dir=/Scripts
mkdir -p $dir

Để tạo tập tin nếu nó không tồn tại,

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

Hoặc nếu bạn thích,

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

6

Bạn có một lỗi cú pháp. Bạn yêu cầu không gian trước và sau [].


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"

Ở trên giả định rằng không có "thủ thuật" nào như tạo một thư mục được gọi /Scripts/file.txt( có thể là một cách buộc tập lệnh luôn luôn nhập vào nhánh if). Nếu "tập tin" là một thư mục, kiểm tra -f sẽ thất bại và lệnh cảm ứng sẽ không thay đổi bất cứ điều gì.


0

cách tiếp cận của tôi

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

đầu ra

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

.


1
Bạn không kiểm tra xem tập tin có tồn tại hay không
PiedPiper

@piepdpiper anh ấy làm, đây là sự tham gia touchmkdir -p
xenoid

cùng ides với nhiều kiểm tra hơn trông giống như: D = / boot / bork; F = fnord; mkdir -p "$ D" && {chạm "$ D / $ F" && echo "đã tạo $ D / $ F OK"; } || {echo "không thể tạo dir '$ D'"; }
jmullee
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.