Broadcast Engineer at BellMedia, Computer history buff, compulsive deprecated, disparate hardware hoarder, R/C, robots, arduino, RF, and everything in between.
4944 stories
·
5 followers

Linux Fu: Shell Scripts in C, C++, and Others

1 Share

At first glance, it might not seem to make sense to write shell scripts in C/C++. After all, the whole point to a shell script is to knock out something quick and dirty. However, there are cases where you might want to write a quick C program to do something that would be hard to do in a traditional scripting language, perhaps you have a library that makes the job easier, or maybe you just know C and can knock it out faster.

While it is true that C generates executables, so there’s no need for a script, usually, the setup to build an executable is not what you want to spend your time on when you are just trying to get something done. In addition, scripts are largely portable. But sending an executable to someone else is fairly risky — but your in luck because C shell scripts can be shared as… well, as scripts. One option is to use a C interpreter like Cling. This is especially common when you are using something like Jupyter notebook. However, it is another piece of software you need on the user’s system. It would be nice to not depend on anything other than the system C compiler which is most likely gcc.

Luckily, there are a few ways to do this and none of them are especially hard. Even if you don’t want to actually script in C, understanding how to get there can be illustrative.

The Whole Shebang

I’m going to assume your shell is Bash. There may be subtle differences between shells, but shells will typically support a way to launch scripts known as the shebang — it’s the use of the hash and exclamation characters (#!) you’ve probably seen at the top of scripts.

When Bash sees you are trying to execute a file, it tries to figure out what kind of file it is using a magic number lookup the way file does. The file command actually uses a library called “magic” to do this and you can run man magic to see a database of sorts that is at work. In theory, there’s a text representation and a compiled version, but many common distributions don’t install the source by default. Regardless, the database looks for certain magic numbers in files to determine their type — programs don’t need to rely on file extensions, for example.

The exact format isn’t important, but a typical entry has an offset to look inside the file and a number or pattern to match. In the case of a shell script the magic number is 0x23 0x21 which is, of course, #!. In particular, system calls that execute something can tell the difference between a shell script and just a random text file.

Normally, you’ll see something like #!/usr/bin/bash which causes the file to run as a Bash script. Of course, this hardcodes the location of the system copy of bash. Some argue this is good because you think you have a chance at getting a known copy of Bash. Others argue that if you have an upgraded copy of Bash in your personal directories it won’t use that. If you agree with the latter group, you can try #!/usr/bin/env bash — that still hardcodes a path, but that executable only sets up the environment.

The interpreter, though, doesn’t have to be Bash or even a proper shell. For example, an Awk program might have #!/usr/bin/awk -f as a first line. So one strategy would be to build a script that can “launch” the underlying C “script.”

That’s one approach, but I took a different one. My original thought was that since #! looks like a preprocessor statement, a script file might be directly usable to the C compiler. That might have been true in the past, but a modern preprocessor throws an error when it sees something it doesn’t expect.

Marking C Files as Bash Scripts

I wanted to keep things simple. The following lines at the very front of a stand-alone C file is enough to make things work:

#!/usr/bin/env bash
#if 0
source cscript_simplec
#endif

The first line tells the system that this is a Bash script. You might be wondering why I would mark it as a Bash script when I’m trying to get to C. Well, the very next few lines are a Bash script. The #if and #endif statements are just comments to Bash. And the source command tells the shell to read cscript_simplec from somewhere on the directory path.

That source never comes back, so what’s after it doesn’t matter to Bash. However, this file will pass to gcc if the executable is out of date. Suppose this file is example.c. There will be an executable example.c.bin in the same directory. (This implies that the first person to run the script needs to have write permission to the directory.)

If the binary is newer than the source file, we simply run it using exec. This causes the program to overlay the current copy of Bash which saves a little memory compared to just running the new program. However, if the source is newer, the script rebuilds the binary first.

There’s a slight problem. Although most of the file will be legal C, the first line isn’t. Yet that line is crucial for the startup. The answer is to cut that line off. Here’s what cscript_simplec looks like:

if [ "$0" -nt "$0.bin" ]
then
  CCOPTS="${CCOPTS:--O3}"
  if ! tail -n +2 "$0" | gcc -x c "${CCOPTS}" -o "$0.bin" -
  then
    echo Compile Error on $0
    exit 999
  fi
fi
exec "$0.bin"

The final command on line 10 cuts off the first line and feeds gcc through the pipe. Because there’s no file name, we have to tell gcc that it is reading a C file (the -x option). You can set CCOPTS or it will default to -O3.

Of course, if you were going to send this out into the wild, you might want to just include this whole chunk — or something similar — in the script and forego the source command. That would work.

Complexity

It’s easy to change the code for something different like C++. Since this is scripting, it is pretty safe to assume there is one file and the executable is directly dependent on only the source file. However, if you want a bit more complexity — some would argue too much for a simple script too — you can turn to make.

Replace cscript_simplec with cscript_make if you want to try that. You’ll have to provide a makefile, too (example.c.make in this case). A suitable one is:

$(SCRIPT_OUT_NAME):$(SCRIPT_NAME)
       gcc -x c $(SCRIPT_NAME) -o $(SCRIPT_OUT_NAME)

Note you have to use $(SCRIPT_NAME) for the source file and $(SCRIPT_OUT_NAME) for the executable. This is a silly example, of course, but you could create a complex set of dependencies and compile options using a makefile. On the other hand, this seems to violate the simple principle, so you are probably better off just writing a normal C program at that point.

If you really need a high-level scripting language, you might consider Python or one of the many other interpreted languages available. However, understanding the mechanism and how to subvert the C compiler might still come in handy someday. After all, you can pull some ugly/beautiful hacks with the preprocessor and compiler.

Read the whole story
tekvax
3 days ago
reply
Burlington, Ontario
Share this story
Delete

If Bob Ross taught math

1 Share

From Toby's "Tibees" YouTube channel: "A math lesson about logarithms inspired by the legendary painter Bob Ross."

Read the whole story
tekvax
4 days ago
reply
Burlington, Ontario
Share this story
Delete

Remembering Johnny Cash on the day he died

1 Share

Any day is a good day to remember country music legend Johnny Cash.

Today, September 12, 2019, is an especially good one because he died on this day, in the year 2003, at the age of 71.

Here are some images, music videos, and details about the man and his work you may not have seen. Share whatever you feel like in the BBS comments, I'd love to hear from other fans.

Here's Johnny Cash singing 'I Walk The Line' on the early television music showcase program Town Hall Party in 1958.

Because you're mine, I walk the line.

Chills.

Photo by Moviestore/Shutterstock (1597211a)
Johnny Cash
Film and Television

Photo by ITV/REX/Shutterstock (933130bd)
'Johnny Cash at San Quentin' - Johnny Cash
ITV ARCHIVE

Photo by Shutterstock
'Johnny Cash at San Quentin' - Johnny Cash
ITV ARCHIVE

Really cool post on IMGUR from a regular high-poster:

John R. "Johnny" Cash was an American singer-songwriter, guitarist, actor, and author. He is one of the best-selling music artists of all time, having sold more than 90 million records worldwide. His genre-spanning songs and sound embraced rock and roll, rockabilly, blues, folk, and gospel. This crossover appeal won Cash the rare honor of being inducted into the Country Music, Rock and Roll, and Gospel Music Halls of Fame.

At birth, Cash was named J. R. Cash. When he enlisted in the United States Air Force, he was not permitted to use initials as a first name, so he changed it to John R. Cash. In 1955, when signing with Sun Records, he started using the name Johnny Cash. After basic training at Lackland Air Force Base and technical training at Brooks Air Force Base, both in San Antonio, Texas, Cash was assigned to the 12th Radio Squadron Mobile of the U.S. Air Force Security Service at Landsberg, Germany. He worked as a Morse code operator intercepting Soviet Army transmissions. On July 3, 1954, he was honorably discharged as a staff sergeant, and he returned to Texas. During his military service, he acquired the distinctive scar on the right side of his jaw as a result of surgery to remove a cyst.

Some of our past posts about Johnny Cash:

Johnny Cash's smart-alecky to-do list / Boing Boing

Music: 'Busted,' Johnny Cash and Ray Charles - Boing Boing

It's Johnny Cash's birthday!

[IMAGES: SHUTTERSTOCK]

Read the whole story
tekvax
4 days ago
reply
Burlington, Ontario
Share this story
Delete

The existential endtime pleasures of watching silent restoration videos

1 Share

It is perhaps in the spirit of our anxious, rickety age that antique tool, machinery, and toy restoration videos are becoming increasingly popular. There is something oddly comforting and therapeutic about seeing the old, the forgotten, the previously reliable (now seized with rust and neglect) being lovingly restored to life.

These videos are simple, quiet (usually with no spoken narrative), and most of the restoration process is carefully shown, from disassembly to cleaning, sanding, repainting to re-assembly and testing. This is a world in which time, Evapo-Rust, a wire wheel, and some rattle-cans of enamel paint can repair the past to near show room luster.

I can't get enough. And for makers, there are lots of great repair and restoration tips embedded in these videos. Here are a few of my favorite channels.

Read the whole story
tekvax
4 days ago
reply
Burlington, Ontario
Share this story
Delete

The largest source of plastic in our fresh water is laundry lint

1 Share

On average, you consume between 74,000 and 121,000 microscopic pieces of plastic every year. Probably much more. Where does it come from? According to new research from Penn State Behrend chemist Sherri Mason, 60 percent of the microplastics in our freshwater comes from laundry lint making its way from your washing machine through wastewater treatment plants. From American Scientist:

As we clean our clothing, sheets, and towels, tiny threads—commonly called microfibers—break off and wash away. To better understand how microbeads and microfibers—collectively making up microplastics—move through the Great Lakes and other freshwater systems, we wanted to understand whether they are removed at wastewater treatment plants.

After collecting and analyzing 90 samples taken from 17 different facilities across the United States, we confirmed that microplastics travel through wastewater treatment plants. On average, each wastewater treatment facility was releasing more than four million pieces of microplastic into U.S. waterways every day: 60 percent fibers, 34 percent beads, and 6 percent films and foams. With 15,000 such facilities in continual operation around the United States, billions of microplastic particles are finding a pathway through our wastewater from our homes to the fresh water we rely on.

(via Scientific American)

image: Amy/Bunnyfrogs (Flickr) Read the rest

Read the whole story
tekvax
4 days ago
reply
Burlington, Ontario
Share this story
Delete

I talk about punch cards, AI and "CODERS" with Joel Spolsky

1 Share

Earlier this summer I stopped by the office of Joel Spolsky, CEO of Stack Overflow, the mammoth forum for software developers, to talk about my new book Coders, which is all about the subculture of programmers and their impact on reality. (And which you can acquire right here folks, step right up.)

We were supposed to talk about coding but at first got totally sidetracked when I noticed Joel had a huge archive of issues of OMNI, so we spent 15 minutes excitedly babbling about the role that magazine played in our nerd youths. (They even hunted down some of the original ads for Heathkit robots.)

When we finally got around to talking about the culture of software creation, it was pretty fun, and they transcribed parts of our talk. Here's Joel talking about how he originally got into coding:

Clive: What was your original pathway into coding?

Joel: My parents were professors at the University of New Mexico, and the University bought a mainframe and didn’t know what do with it. They gave every professor an account. And the professors gave those to their kids.

So I was part of a group of teenage kids just hanging around the computer center trying to figure stuff out.

Clive: So what was it, FORTRAN?

Joel: It had an interactive operating system because those had gotten trendy at universities. They had an interactive terminal system that had BASIC, FORTRAN, and PL1. Many, many years later I realized there was no way they had enough memory for three compilers and in fact what they had was a very simple pre-processsor that made Basic, Fortan, and PL1 all look like the same mush. It was a very crappy subset of each of those three languages.

Clive: Oh my god, that’s trippy. For me, it was the generation of BASIC computers you could plug into a TV, that’s what got me in. But also, hilariously, my high school in Toronto had set up a computer programming course you could take in your fourth year, where we learned FORTAN on punchcards. You fed them in and came back two hours later for them. I’m glad to have done it, because when I interview coders in their 70s and 80s, we can bond over tripping while walking down the hallway carrying a stack of 100 cards you forgot to number.

True story, that latter one. In my high school I took the single class they offered in computer programming, which for me was 1986. I and my friends had already been programming for years in BASIC, so we showed up thinking that we'd learn that, or maybe Pascal or Assembly.

Nope. It turns out that some years previously -- likely, a decade previously -- they'd signed up for an agreement to use a semi-decommissioned PDP-somethingorother parked in the basement of the University of Toronto, on a timeshare basis, to teach us FORTRAN on punchcards, batch-style. We were kind of baffled; by the mid-80s, punchcards seemed pretty retro, since realtime coding on a screen seemed the Way of the Future. But like I said in the interview, I'm now glad I got a chance to try my hand at that craft.

I've occasionally toyed with the idea building a punchcard reader for programming Javascript, just because why not. Maybe some weekend I'll roll up my sleeves and do it.

Read the whole story
tekvax
4 days ago
reply
Burlington, Ontario
Share this story
Delete
Next Page of Stories