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.

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
  • 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 Feb 19 '18 at 05:50
  • If you can't use lsof, you could reimplement what lsof does (scan through /proc/$pid/fd/*). – phemmer Feb 19 '18 at 05: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. – abhishek mishra Feb 19 '18 at 06: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. – abhishek mishra Feb 19 '18 at 06: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 Feb 19 '18 at 06:48
  • I don't understand your response on why you can't scan /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
  • @Patrick only way to use * /proc/$pid/fd/* * on net that I came across was to put the running process into a string variable using the pid of the process and check if the string length is 0 then file is not in use else in use, So for this to work the process has to shut down in order for me to know that the file is not under use, but as I mentioned earlier the process that is writing to the file is providing a lot more services that are required by the overall system, So how should I know when that file has been written, Is their a way to know the pid of a particular sub process? – abhishek mishra Feb 20 '18 at 05:01
  • Nevermind anyway. For some reason I thought I read you were using linux, not QNX. So the idea won't work. – phemmer Feb 20 '18 at 05:12

3 Answers3

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.

Fido-X
  • 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
  • HEY! WHAT'S WITH THIS FORMATTING HERE? WHERE ARE #? – Fido-X Feb 19 '18 at 09:35
  • 2
    Please 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
  • 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 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
  • 1
    This 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
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!!

Marc
  • 439
  • 2
  • 3
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).

Kusalananda
  • 333,661