0

I'm writing a mock-grading script in bash. It's supposed to execute a C program which will give some output (which I redirect to a file.) I'm trying to (1) make it timeout after a certain duration and also (2) terminate if the output file reaches a certain file size limit. Not sure how to go about either of these. Any help? Thanks.

3 Answers 3

3

There's a GNU coreutil command timeout to do timeouts.

Investigate ulimit -f 32 to set the maximum file size (to 16 KiB; it counts in 512 byte blocks).

Objection:

ulimit is [not] suitable because I have to create other files as well. I need to limit only one of them.

Counter: Unless the program must create a big file and a little file and you have to limit just the little file, you can use a sub-shell to good effect:

(
ulimit -f 32
timeout 10m -- command arg >file
)

The limit on file size is restricted to the commands in the sub-shell (which is marked by the pair of parentheses).

Sign up to request clarification or add additional context in comments.

4 Comments

I don't think ulimit is suitable because I have to create other files as well. I need to limit only one of them.
This solution works well for the file limit condition. However, I can't use the coreutils (the machines this has to run on don't have them installed.) Is there another option for timeout?
@Chris, you could start another script in the background that sleeps nnn seconds and then sends a signal to the parent PID, which the parent could handle with trap. Racey, but it should work.
GNU coreutils are things like 'ls' - and current versions of coreutils (8.4 verified present; 6.12 verified absent) contain timeout.
0

you can use timeout command eg

timeout -s 9 5s ./c_program > file

to check file size, you can stat the file, then do if/else

limit=1234 #bytes
size=$(stat -c "%s" file)
if [ "$size"  -gt "$limit" ] ;then
  exit
fi

see also here if you can't use these GNU tools, or here for some other inspirations.

Comments

0

This starts yourcommand, redirecting output via dd to youroutputfile and putting a limit of 10000000 bytes on it: dd will terminate and SIGPIPE will be sent to yourcommand

yourcommand | dd of=youroutputfile bs=1 count=10000000 &

This will wait 5 seconds and kill yourcommand if not already terminated:

sleep 5
kill %yourcommand

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.