3

I have the following two files in my working directory:

test.txt and img.jpg

test.txt is a character special file

img.jpg is a block special file

Now I want to find if these files are character special files or block special files using shell script.

I have written the following two shell scripts:

First-

#! /bin/bash echo -e "Enter file name: \c" read file_name if [ -c $file_name ] then echo Character special file $file_name found else echo Character special file $file_name not found 

Input:

test.txt 

Output:

Character special file test.txt not found 

Second-

#! /bin/bash echo -e "Enter file name: \c" read file_name if [ -b $file_name ] then echo Block special file $file_name found else echo Block special file $file_name not found 

Input:

img.jpg 

Output:

Block special file img.jpg not found 

Where am I going wrong?

2 Answers 2

6

You're slightly wrong in your assumptions. Block special files are things like hard drive partition, memory devices. For instance, the main partition of my hard-drive is /dev/sda1. The test's (aka [) -b flag will work for that, but it won't work for a picture file, which is considered a regular file.

$ test -b ./Pictures/NOTEBOOKS/8.jpg && echo "It's a block device" || echo "Not a block device" Not a block device $ test -b /dev/sda1 && echo "It's a block device" || echo "Not a block device" It's a block device 

Character devices are things like tty and serial consoles. For instance:

$ test -c /dev/tty1 && echo "It's a character device" || echo "Not a character dev" It's a character device 

And stat can tell you pretty much this same information, just in text form instead of exit status like test does:

$ stat --printf "%n\t%F\n" /dev/tty1 /dev/sda1 ./mytext.txt ./Pictures/NOTEBOOKS/8.jpg /dev/tty1 character special file /dev/sda1 block special file ./mytext.txt regular file ./Pictures/NOTEBOOKS/8.jpg regular file 

What you should be doing is using file command, and checking its output:

$ file ./Pictures/NOTEBOOKS/8.jpg ./Pictures/NOTEBOOKS/8.jpg: JPEG image data, JFIF standard 1.02, aspect ratio, density 100x100, segment length 16, baseline, precision 8, 750x750, frames 3 $ file /dev/sda1 /dev/sda1: block special (8/1) $ file mytext.txt mytext.txt: ASCII text 
4
  • Thanks for your answer, please view this video, youtube.com/…, I am learning shell scripting by following this online tutorial Commented Jul 16, 2017 at 9:17
  • 1
    Your answer makes my understanding crystal clear. However at the same time it means that the author of the above said tutorial is completely wrong. Commented Jul 16, 2017 at 9:31
  • 1
    @Sonevol I watched the video, found the part where they mention it at 7:22. Yep, the author of the video is wrong. A picture or video file is still considered regular file, it is not block file. A text file with words in it is not character file. Character file (or more commonly, character devices) read characters, so say I have Arduino or Raspberry Pi on /dev/ttyUSB0 , and if I write characters there, those devices will read what I'm sending to them. Commented Jul 16, 2017 at 9:36
  • Actually, I'd suggest you read this: unix.stackexchange.com/a/60147/85039 Commented Jul 16, 2017 at 9:37
3
$ cat test-c.bash #! /bin/bash echo -e "Enter file name: \c" read file_name if [ -c $file_name ] then echo Character special file $file_name found else echo Character special file $file_name not found fi $ bash test-c.bash Enter file name: /dev/tty Character special file /dev/tty found $ cat test-b.bash #! /bin/bash echo -e "Enter file name: \c" read file_name if [ -b $file_name ] then echo Block special file $file_name found else echo Block special file $file_name not found fi $ bash test-b.bash Enter file name: /dev/sda Block special file /dev/sda found 

Except for the missing fi in your programs, they do what one would expect.

Your assumption...

test.txt is a character special file

img.jpg is a block special file

...probably is wrong if you have not created them to fulfil this e.g. using mknod.
(See man mknod.)

So if your test files are what the names are hinting to, they are just plain normal (regular) files.

What were you looking for?

A way to distinguish between text files and binary files like in DOSish operating systems?

This is a relict of CP/M days or even older. The filesystem did track the file sizes in blocks and therefor text files needed an end of file character to flag the end of valid text.

The consequence is, that concatenation of binary files and text files has to be done differently.

Unixish filesystems track the file's size in blocks and in actually used bytes, so there is no need to flag the text end using a special end character.

If you want to guess what's inside a file, you can use the file command:

$ file 20170130-094911-GMT.png 20170130-094911-GMT.png: PNG image data, 744 x 418, 8-bit/color RGBA, non-interlaced $ file calendar.txt calendar.txt: ASCII text 

HTH!

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.