Category: bash

Passing argument to a curl downloaded script

To add an argument to the execution of the script you’re downloading and running via curl, you can modify the command like this:

curl http://aaa.com/script.sh | sh -s -- scan
  • sh -s : This tells sh to accept input from stdin (which comes from curl via the pipe |).
  • : This marks the end of options for sh. Everything that follows will be considered arguments for the script.
  • scan : This is the argument you want to pass to the script

You can add other arguments by separating them with spaces after “scan” if needed.

This method allows you to execute the downloaded script with arguments, just as if you were running it directly on your system.

BASH | Hex to Decimal Conversion

To convert a hexadecimal value to decimal using Bash, you can use either the printf command or bc. Here’s how to do it with printf:

printf "%d\n" 0x3000

This will output the decimal value corresponding to 0x3000.

Alternatively, using bc:

echo "ibase=16; 3000" | bc

This interprets 3000 as a hexadecimal value (base 16) and converts it to decimal.

In both cases, the result will be 12288.

JSON text filtering with jq

I frequently have to intereact with some json files , since bash is the main tool i use day to day i must master the usage of jq, but i noticed that the vast majority of totorials on jq usage just sucks.
I’m going to write some kind of memo to remember the main command that i use most of the time
lets take this dummy contact.json file

{
  "contacts": [
    {
      "name": "John Smith",
      "phone": "(123) 456-7890",
      "email": "john.smith@example.com",
      "sex": "male",
      "position": "Manager",
      "birthday": "1985-06-23",
      "devices": [
        {
          "type": "laptop",
          "model": "MacBook Pro",
          "serial_number": "ABCD1234",
          "issued_date": "2022-01-15"
        },
        {
          "type": "phone",
          "model": "iPhone 12",
          "serial_number": "EFGH5678",
          "issued_date": "2022-01-15"
        }
      ]
    },
    {
      "name": "Jane Doe",
      "phone": "(234) 567-8901",
      "email": "jane.doe@example.com",
      "sex": "female",
      "position": "Sales Representative",
      "birthday": "1990-02-14",
      "devices": [
        {
          "type": "laptop",
          "model": "Dell XPS 13",
          "serial_number": "IJKL9012",
          "issued_date": "2022-03-01"
        }
      ]
    },
    {
      "name": "Bob Johnson",
      "phone": "(345) 678-9012",
      "email": "bob.johnson@example.com",
      "sex": "male",
      "position": "IT Specialist",
      "birthday": "1982-11-30",
      "devices": [
        {
          "type": "laptop",
          "model": "ThinkPad X1 Carbon",
          "serial_number": "MNOP3456",
          "issued_date": "2022-02-10"
        },
        {
          "type": "phone",
          "model": "Samsung Galaxy S21",
          "serial_number": "QRST7890",
          "issued_date": "2022-02-10"
        }
      ]
    }
  ]
}

to list the name of all the male employes in the json file
cat contact.json | jq '.contacts[] | select(.sex=="male") | .name'

this one is truly awesome , display the name of all employes that are more than 35 years old using their birthday.
cat contact.json | jq '.contacts[] | select((.birthday | strptime("%Y-%m-%d") | mktime) <= (now - 35*365*24*60*60)) | .name'

this one is going to list all the phone and their issued date
cat contact.json | jq '.contacts[].devices[] | select(.type=="phone") | {model: .model, issued_date: .issued_date}'

To display the devices issued after 2022-02-12 and their owner’s name, you can use the following jq command:
cat contact.json | jq '.contacts[] | {owner: .name, devices: [.devices[] | select(.issued_date > "2022-02-12") ] } | select(.devices != [])'

Using bash and gatttool to get readings from Xiaomi Mijia LYWSD03MMC Temperature Humidity sensor

There is a new inexpensive Temperature and humidity sensor by xiaomi.
This time is no longer round ,

Xiaomi Mijia LYWSD03MMC Bluetooth 4.2 Temperature Humidity sensor

if you like me would like to get the temperature and humidity data from time to time to import in a graphing tool like grafana, there is a simple solution using classic bash tools and gatttool.
First you have to indentify the mac-address of your little sensor, for this , just make sure the sensor is in range of your linux device ans launch a
hcitool lescann

this command will spit out all the bluetooth devices in range
just find the line with the name of the device and copy the mac address A4:C1:38:8C:77:CA LYWSD03MMC

then you must start a little bash script like this :

#!/bin/bash
bt=$(timeout 15 gatttool -b A4:C1:38:8C:77:CA --char-write-req --handle='0x0038' --value="0100" --listen)
if [ -z "$bt" ]
then
echo "The reading failed"
else
echo "Got data"
echo $bt temphexa=$(echo $bt | awk -F ' ' '{print $12$11}'| tr [:lower:] [:upper:] )

humhexa=$(echo $bt | awk -F ' ' '{print $13}'| tr [:lower:] [:upper:])
temperature100=$(echo "ibase=16; $temphexa" | bc)
humidity=$(echo "ibase=16; $humhexa" | bc)
echo "scale=2;$temperature100/100"|bc
echo $humidity
fi

this is a skeleton that you can improve , but for now it pretty much work like that ,

first it use gatttol to connect to the sensor and listen for 15 sec
During these fifteen seconds , you can be pretty much sure to receive at least some data like this :

Characteristic value was written successfully Notification handle = 0x0036 value: 58 03 47 a0 0b Notification handle = 0x0036 value: 55 03 47 a0 0b

this tell me that during the 15 sec of connection i received the information that i need two times.
what i’m after are the value 58 03 for the temperature , and 47 for the humidity.

the temperature is little endian format its mean that the two group must be inverted before decoding the data. i invert the values with awk and decode them using bc.
bc doesn’t like when the hex values are not capitalised so tr is used to do that.

bc then give you the temperature multiplied by 100. relaunch bc to divice per 100,

For the humidity its simpler , you get the value in one step without inverting anyting

Then you can do what you need with theses two vars , insert then in some database etc ..

there is room from improvement: for example this script is not capable of decoding negative temperature.
i will post an improved version when i figure out how to do it

bash : Random number in OpenWRT

On some light linux environement running busybox or openWRT you will notice that you don’t have access to the $RANDOM variable ,
the date command is also incomplete so you can’t use the tail of the nanosecond date to have a random number.

.

Using this command you will get a random number beetween 0 and 69.
if you wish to change the range of the random numbers , just edit the regex in the grep part

Using AWK to display the min the max and the average of a list

awk is a extremely powerful tool !
i’m always surprised how much you can do with it.

My latest finding is pretty amazing.

Lets say you have a list of numbers , and you want to figure out the bigger number , the lower number , and the average of all the numbers in the list.

you can use the following awk code to print minimum, maximum and average.

The output is going to  be :
avg 32.93 | max 100.1 | min 1.5

you can also use this code with decimal numbers

 

Use the keyboard on a remote machine over SSH?

If you use a Linux box to display some infos in a public space , you might not have the possibility to connect a mouse and keyboard every time you need to click on the page.

For example, at work we use a TV to display some metrics with grafana,
Sometime, when we reboot the machine , the identification cookie will be outdated and the browser will land on the authentication page instead.
Since the machine has no keyboard and mousse attached this cause some issues , .
So I’ve used the tool xdotool that allow a privileged ssh user or a script to interact with the mouse and keyboard

An important step is to select the screen on witch you want to send mouses clicks and keystrokes.

After that lets say your screen is displaying a full-screen browser with a login page ,
By default the cursor is already in the login form.

for the example , the login/password are going to be admin/admin

you are now logged and you dashboard will display