I am facing an issue where I have to write a shell script to read a file only if it is not used or under write by any other program. I cannot use lsof as this script is going to run on the embedded hardware running QNX with very basic shell functionalities hence no third party-tools and libraries.
3 Answers
I think i've got the answer. Put this as part of your script:
#!/bin/bash
# Script to prevent writing to a certain file.
# This should be adjusted to your needs, replace all /paths/ and <xxxxxxx>
# with your true paths and filenames.
chmod +r /path_to_file/<filename>
<now_do_what_you_want_with_that_file, command(s) here>
for a in {120..1}; do echo -n "$a..." && sleep 1; done # In 120 seconds <filename> will be writable.
chmod -r /path_to_file/<filename>
Also a script can be created to copy that file to another location, then read it's copy which is neither open nor in use, and after it's done delete it after X amount of seconds.
This can be repeated all you want if need be.

- 16,527

- 156
- 5
-
Setting a file to read only during an other program is writing is maybe not a good idea. This can cause a lot of strange errors and no one will be able to find out why this happens unless you know the other script. – Marc Feb 19 '18 at 09:35
-
-
2Please read https://stackoverflow.com/help/formatting for general idea on how to format answers – Sergiy Kolodyazhnyy Feb 19 '18 at 09:40
-
@Marc, until he tries it we can't know and if it does cause error(s) he can relax - he'll just comment out some lines from the script and it won't be read-only. That what he wants to achieve is a complicated task... and i believe that there's another, hidden problem there. – Fido-X Feb 19 '18 at 09:40
-
Thank you, @SergiyKolodyazhnyy, how did you make it that way? You enclosed into something, right? – Fido-X Feb 19 '18 at 09:41
-
Ok. I will. I just saw your comment with link to instructions on formatting. Thank you again. – Fido-X Feb 19 '18 at 09:42
-
1This does not answer the question. Any process can still access the file and read it or write to it (for example, a copy of the script in the answer). The question requires mandatory file locking implemented in the kernel. This is seldom implemented in Unix, but I can't say anything specific about QNX. – Kusalananda Feb 19 '18 at 10:06
-
@Kusalananda, he asked about making a script: "I am facing an issue where I have to write a shell script to read a file only if it is not used or under write by any other program." I gave him some hints/ideas. let's concentrate on how to create some script that would help him. – Fido-X Feb 19 '18 at 10:19
-
@Fido-X Well, that's one of the basic file locking operations: Acquire a shared (read) lock on a file. The lock will be acquired when no exclusive (write) locks are held. – Kusalananda Feb 19 '18 at 10:22
-
1This seems like a very poor solution to a different problem than the OP was asking about. – Shadur-don't-feed-the-AI Feb 19 '18 at 13:05
If you don't know if the file is currently written and don't have a chance to find out if a program is using it, you can think about checking the ctime,mtime and atime. You can do this with the "stat" command which should be available in the most systems. You can check it 3-4 times and if there is no difference, write it. Note that the atime (access time) will always change as long as you check it!
An other idea is to make a copy of you file and work with that copy. After doing your stuff, make a diff you your modified copy and the original and replace it if there are no other changes. Else, you can try to work with "diff" and "patch". I recommend to make a backup before doing this!!

- 439
- 2
- 3
Disclaimer: I don't know much about QNX, and even less about embedded devices.
What you are asking about is basically about file locking: A process tries to acquire a shared lock (read lock) on a lock file to perform some operations. If an exclusive lock (write lock) is held on the same lock by another process, the first process will block until the exclusive lock has been released. Or reversed, a process may acquire an exclusive lock only if there are no other processes with shared active shared/exclusive locks.
To do mandatory file locking, this has to be supported by the kernel. There are very few Unix systems that implements this in a way that works reliably from a shell script (for Linux, see this text from 2007, and this question on StackOverflow).
Advisory locking is implemented in userspace by programs such as flock
. This type of file locking requires processes to cooperate which means that they will need to explicitly ask for read or write access to the lock file. At the same time, an uncooperative process may still ignore the locking mechanism.
The question "Flock doesn't seem to be working" is about advisory locking using flock
in the shell.
See also: What Unix commands can be used as a semaphore/lock? (this is also about advisory locking, and some answers are using mkdir
for this purpose as it's an atomic operation).

- 333,661
-
Unfortunately flock is also not supported by the target that I am working with. – abhishek mishra Feb 20 '18 at 04:46
lsof
, you could reimplement whatlsof
does (scan through/proc/$pid/fd/*
). – phemmer Feb 19 '18 at 05:53flock
) on QNX? Most Unix systems does not implement mandatory file locking. – Kusalananda Feb 19 '18 at 06:48/proc/$pid/fd/*
manually. If you're saying that you don't want to do that because something might open the file for writing after you've performed the check, your only option is to do something to prevent the file from being opened for writing, which really means the thing doing the writing has to use file locking so you can lock it. If it doesn't then you're hosed. – phemmer Feb 19 '18 at 13:32