2

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.

8
  • Which program(s) are writing to that file? Do you need all text from that file or just certain lines of text starting with some_characters, words?
    – Fido-X
    Commented Feb 19, 2018 at 5:50
  • If you can't use lsof, you could reimplement what lsof does (scan through /proc/$pid/fd/*).
    – phemmer
    Commented Feb 19, 2018 at 5:53
  • @Patrick , I cannot use [ls -l /proc/PID/fd] as the process that is reading the file is not just reading the file but it is doing a lot more things so it will continue running even after writing to the file. Commented Feb 19, 2018 at 6:34
  • @Fido-X , the program that is writing to that file is a huge one and I want to read whole of the file and not some random text. Commented Feb 19, 2018 at 6:34
  • Is your question about doing mandatory file locking (not advisory file locking with e.g. flock) on QNX? Most Unix systems does not implement mandatory file locking.
    – Kusalananda
    Commented Feb 19, 2018 at 6:48

3 Answers 3

0

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.

10
  • 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
    Commented Feb 19, 2018 at 9:35
  • HEY! WHAT'S WITH THIS FORMATTING HERE? WHERE ARE #?
    – Fido-X
    Commented Feb 19, 2018 at 9:35
  • 2
    Please read stackoverflow.com/help/formatting for general idea on how to format answers Commented Feb 19, 2018 at 9:40
  • 1
    This 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
    Commented Feb 19, 2018 at 10:06
  • 1
    This seems like a very poor solution to a different problem than the OP was asking about. Commented Feb 19, 2018 at 13:05
0

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!!

0

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).

1
  • Unfortunately flock is also not supported by the target that I am working with. Commented Feb 20, 2018 at 4:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .