|

[Bash Challenge 6] Test Your Bash Scripting Knowledge With This Puzzle

Bash Challenge Programming excercise

Welcome to the Bash Challenge #6 by Yes I Know IT & It’s FOSS. In this weekly challenge, we will show you a terminal screenshot, and ask you to explain why the result is not the one we were expecting.

Of course, the most amusing, and most creative, part of the challenge will be to find how to fix the command(s) displayed on the screen to obtain the correct result. Last week’s Bash Challenge was level one but we have up the ante this time and we have got a level 2 problem for you.

You can also buy these challenges (with unpublished challenges) in book form and support us:

[irp posts=”17248″ name=”Bash It Out! Bash Script Puzzle Book by It’s FOSS is Available Now!”]

Ready to play? So here is this week’s challenge:

The file that survived to rm

Bash Script Challenge

Today, our description is quite short: I have three files in a directory. As root, I used rm * in that directory. But there is one file that obstinately refuses to be deleted:

root:011# ls -ls
total 12
4 -rw-r--r-- 1 root root 29 nov 21 21:25 a
4 -rw-r--r-- 1 root root 29 nov 21 21:25 b
4 -rw-r--r-- 1 root root 29 nov 21 21:23 c
root:012# rm *
rm: cannot remove 'c': Operation not permitted
root:013# ls -ls
total 4
4 -rw-r--r-- 1 root root 29 nov 21 21:23 c

Your challenge is to find:

  • What prevented the third file to be deleted?
  • How to actually delete that file?

We’re looking forward to read your solutions in the comment section below!

Few details

To create this challenge, I used:

  • GNU Bash, version 4.4.5 (x86_64-pc-linux-gnu)
  • Debian 4.8.7-1 (amd64)
  • All commands are those shipped with a standard Debian distribution
  • No commands were aliased

The solution

How to reproduce

Here is the raw code we used to produce this challenge. If you run that in a terminal, you will be able to reproduce exactly the same result as displayed in the challenge illustration (assuming you are using the same software version as me) :

 # as root :
 cd /tmp
 rm -rf ItsFOSS
 mkdir -p ItsFOSS
 cd ItsFOSS
 date > a
 date > b
 date > c
 sudo chattr +i c
 clear
 ls -ls
 rm *
 ls -ls

What was the problem ?

I used the chattr command to set the (i)mmutable Linux filesystem attribute for the file c. Depending your exact filesystem, all attribute changes are not available.

But here, I am using and ext2 filesystem that does support the i flag. And to quote the man:

       A  file with the 'i' attribute cannot be modified: it cannot be deleted
       or renamed, no link can be created to this file  and  no  data  can  be
       written  to  the  file.  Only the superuser or a process possessing the
       CAP_LINUX_IMMUTABLE capability can set or clear this attribute.

So basically after the chattr +i the file is locked until we clear this flag. Please notice the attribute is stored in the filesystem. It will survive reboots & filesystem unmount/mount cycles.

How to fix that ?

First, we can check the explanation above by using the lsattr command :

root:014# lsattr c
----i-------------- c

Clearly, the (i)mmutable flag is set. So, in order to remove that file (or to make any change to it), I have to clear that flag first. After that, I can do whatever I want on the file as usual :

root:015# chattr -i c
root:016# lsattr c
------------------- c
root:017# rm c
root:018# ls -ls
total 0

If you’re not aware of the existence of chattr, its effects can be quite puzzling. Worth mentioning chattr is a Linux-specific command, originally written for the ext2/3/4 filesystems. But today’s some of its feature are supported by other filesystems.

In the BSD-world, there is a similar command called chflags. Read more on Wikipedia(https://en.wikipedia.org/wiki/Chattr) for a gentle introduction to that commands compared to chattr.

We hope you enjoyed that challenge. Stay tuned for more fun !

Similar Posts

  • Hmm. I’ve had this type of problem in real life scenarios and its always been nonprintable characters in the filename rather than someone running an isoteric command to change the attributes. I’m sure this happens occasionally but bad programs writing nonprintable characters has happened more in my experience! (Filename corruption in c++ being the issue!)

  • * the file has the i-bit set.. or attribute.. whatever you want to name it.. it’s immutable – that’s what’s wrong.
    listing the files with just -ls will not show the extra attributes.. I’m not sure if -ols would have.. think so.. not sure :-)

    * what I do know that in linux you can :

    chattr -i c && rm c

    * in openbsd :

    chflags noschg c && rm c

    * and if you weren’t root but set immutable yourself and forgot about it, it would have been :

    chflags nouchg c && rm c

    * and in freebsd you pretty much can’t miss, since they accept just too much variants of what just should be 1 option :

    chflags noschg c && rm c
    or
    chflags noschange c && rm c
    or
    chflags nosimmutable c && rm c

    * and since I’m typing too much anyway.. on Solaris :

    chmod S-vnounlink c
    rm c

  • What are 011, 012 and 013? Maybe the working directory in $PS1, and not the line numbers?
    I would like to see the output of
    $ pwd # print working directory
    In this case, we can delete the file “c” this way:
    $ cd ../012 ; /bin/rm c