Write Bash Script Which Accepts Argument or User Input

Changing ownership of directories and files. Typing chown -R www-data:www-data * is annoying repetitive task I have to run.

I want a simple version of that command. Like chownership. Or chwn to be even shorter.

The fastest way to do it is by making alias inside .bashrc or .bash_profile

But today I’ll go the other way. Write it in a bash script.

To create a globally available executable bash script, I save the file in /usr/local/bin/. That is for saving even more time rather than typing the full path of the executable.

cd /usr/local/bin/
nano chwn
chmod +x chwn

#1 The First Way: Passing Argument(s)

Bash script executes by typing chwn username. This is the most similar method like the chown’s nature command.

#!/bin/bash

chown -R $1:$1 *

#2 The Other Way: Passing Input(s)

Bash script executes by typing chwn <enter> then the following prompt, asking what user and group I want to apply. Type username <enter>.

This other way uses dual steps. Impractical. Unnatural method as the chown command. I’m not using this. This is more suitable for a program with more complex routines. Like installing multiple packages in a one-go.

#!/bin/bash

echo "user?"
read user
chown -R $user:$user *
Install the Latest MariaDB Release with EasyEngine 3
dpkg: error processing archive /var/cache/apt/archives/mariadb-server-10.1_1%3a10.1.45+maria-1~bionic_amd64.deb (--unpack):
new mariadb-server-10.1 package pre-installation script subprocess returned error exit status 1
Errors were encountered while processing:
/var/cache/apt/archives/mariadb-server-10.1_1%3a10.1.45+maria-1~bionic_amd64.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)

Error di atas adalah problem yang muncul bersamaan dengan pandemi COVID-19 di tahun 2020. Ketika update Ubuntu via apt update -y, proses terhenti karena ada error saat memperbarui mariadb.

Solusi tercepat saat itu adalah dengan uninstall mariadb-server sama sekali dari server.

Loh kok dibuang? Iya, karena mariadb-server tidak terpakai sama sekali di local host, karena database pakai remote host.

Namanya quick fix jelas tidak mengobati penyakit sebenarnya. Hanya menutupi luka sementara, agar proses apt update tetap tereksekusi dengan sukses hingga selesai.

[email protected]:~# apt install mariadb-server -y
Reading package lists… Done
Building dependency tree
Reading state information… Done
Correcting dependencies… Done
The following additional packages will be installed:
mariadb-server-10.1
Suggested packages:
mailx mariadb-test tinyca
The following NEW packages will be installed:
mariadb-server-10.1
0 upgraded, 1 newly installed, 0 to remove and 108 not upgraded.
21 not fully installed or removed.
Need to get 0 B/7,234 kB of archives.
After this operation, 89.5 MB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Preconfiguring packages …
(Reading database … 102169 files and directories currently installed.)
Preparing to unpack …/mariadb-server-10.1_1%3a10.1.45+maria-1~bionic_amd64.deb …
Failed to stop mysql.service: Unit mysql.service not loaded.
invoke-rc.d: initscript mysql, action "stop" failed.
invoke-rc.d returned 5
There is a MySQL server running, but we failed in our attempts to stop it.
Stop it yourself and try again!
dpkg: error processing archive /var/cache/apt/archives/mariadb-server-10.1_1%3a10.1.45+maria-1~bionic_amd64.deb (--unpack):
new mariadb-server-10.1 package pre-installation script subprocess returned error exit status 1
Errors were encountered while processing:
/var/cache/apt/archives/mariadb-server-10.1_1%3a10.1.45+maria-1~bionic_amd64.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)
[email protected]:~# cd

Solusinya? Baru dapat bulan Agustus ini: menambahkan repository MariaDB 10.2.

curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup \ | sudo bash -s -- --mariadb-server-version=10.3 --skip-maxscale

Setelah itu baru kita bisa install mariadb-server dengan selamat dan sukses.

sudo apt update && sudo apt install mariadb-server

Gitu aja ternyata. Asv sekali …

Referensi hasil googling dari sini dan sini.

macOS Change the Default Save Location of Screenshots

MacOS have a built-in screenshot feature which can be used right off the bat. This feature is an important one which I previously never met in Windows environment. It’s so helpful to chat and give instant example of my screen.

However, I took screenshots often, so it started to pile up on my desktop. Something I’m not very fond about. Fortunately, I can set up a dedicated folder for them and have them automatically save there. This can be done with a simple Terminal command

First, I create a dedicated screenshots folder via Finder.

Create Screenshots Folder

Open Terminal, and fire these commands. Don’t forget to change the path on the first command. The easy way rather than typing the path by yourself is by dragging the newly created screenshots folder into the Terminal, after you type

defaults write com.apple.screencapture location /Users/username/Pictures/Screenshots
killall SystemUIServer

The first command, sets the screenshot location to defined path, and the seconds restarts the SystemUIServer so the alteration can be recognized instantly by system.

Nginx Block Countries Using GeoIP Modules

Nginx block countries using GeoIP modules. Fortunately using EasyEngine installation, nginx is already installed with -with-http_geoip_module option. You can check with this command

nginx -V 2>&1 | grep -- 'http_geoip_module'

The IP database is also already downloaded on /usr/share/GeoIP/GeoIP.dat

1. Map and Declare $allowed_country Variable

This means the only steps we need to do is create a conf file inside /etc/nginx/conf.d/ directory. For a reminder, creating a conf file inside the conf.d directory will be auto-included from nginx.conf file. The configuration content below is meant to be put inside http block. Let’s name it badcountries.conf.

geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $allowed_country {
    default yes;
    CN no;
    ID no;
    IN no;
    RU no;
}
geo $exclusions {
    default 0;
    10.8.0.0/24 1;
}

2. Check $allowed_country Variable with Active IP Visitor

Next step is check the $allowed_country variable against the current visitor’s IP address. Put this code inside server block.

if ($allowed_country = "no") { 
  return 444; 
}

Restart nginx after editing is done.

service nginx restart

Now, every visitors coming from countries you defined as no inside badcountries.conf will be served with 444 error code.

For the list of ISO 3166 country codes you can put inside badcountries.conf file, follow this link.

Brew Install PHP Redis on MacOS High Sierra 10.13

After upgrading to MacOS High Sierra (or any upgrade process previously), first thing I need to check is the local webserver status: apache, php, redis, mysql. Brew install php redis. Thankfully, MacOS High Sierra is now shipped with PHP 7.1 installed, which met the new standard for my future web developments.

PHP-redis is a must-installed library since I love the MySQL + Redis tandem for handling data storage and requests. Of course, along with the newly upgraded OS, the Apache installation in fresh installed with standard “It works!” welcome page.

Now, into the installation steps.

1. Install php71-redis Library

Easier said, I simply shot brew install php71-redis into Terminal and then served with Error, suggesting that I need to install Xcode Command Line Tools.

xcode-select --install

2. Unlink Previous PHP 5.6 Libraries

I tried to install again the library, but another error came along. It said the installed formulae was conflicting: different php versions install the same binaries. It suggested me to unlink all php 5.6 libraries. Ok then..

brew unlink php56

3. Install php71-redis (Again)

Hopefully this attempt for installing php71-redis library was a successful one.

brew install php71-redis

brew install php redis php7.1 macos high sierra

4. Edit php.ini; Include php71-redis Extension

Edit /etc/php.ini, add the extension as follows. If the php.ini file not exist, copy the php.ini~previous. Don’t forget to include the igbinary extensions too, so you won’t get problem my previous php56-redis module not loaded here.

5. Restart Apache

Final steps

sudo apachectl restart
dyld: Library not Loaded MacOS High Sierra

MacOS High Sierra problem when executing php command through terminal. Problem? An error stating dyld library not loaded.

dyld: Library not loaded: /usr/local/opt/jpeg/lib/libjpeg.9.dylib
Referenced from: /usr/local/bin/php
Reason: image not found
Abort trap: 6

According to this stackoverflow post, I need to uninstall current version of libjpeg. Use --ignore-dependencies to force uninstallation since libjpeg is needed by other library dependencies.

brew uninstall libjpeg --ignore-dependencies

Reinstall with: brew install libjpeg

dyld library not loaded /usr/local/opt/jpeg/lib/libjpeg.9.dylib

The command will produce warning since latest version of libjpeg has already installed Warning: jpeg 9b is already installed, it's just not linked.

Simply we can shoot brew link jpeg command into Terminal, and all our problem should be solved.

php56-redis Module Not Loaded in PHP-CGI macOS Sierra

After macOS Sierra 10.12.6 Update, my php56-redis module is not working, causing some of my PHP applications cannot communicate with Redis as storage engine. My confusion raises when the module is loaded in PHP-CLI but not in PHP-CGI. It means, if I type php -m in command line, redis shows up. But, if I access via browser via phpinfo(); nothing says about redis.

I googled for nearly two days, until I realized that I haven’t look for a file which I should investigate the first time any errors occured in PHP: error_log. In macOS, the logs are located in /var/log/apache2/ so the file is located on /var/log/apache2/error_log.

I open the file via Sublime and then voila … Here comes the essential hint.

PHP Warning:  Cannot load module 'redis' because required module 'igbinary' is not loaded in Unknown on line 0

I remember that I never typed any of these igbinary module in php.ini, so this is new case for me. Maybe after macOS Sierra last update, the module is not loaded automatically.

php56-redis Module Must Be Defined Manually in php.ini

I’m sure I have this igbinary module installed, however I try to install it again via Homebrew. Of course, it results in error message homebrew/php/php56-igbinary 2.0.4 already installed. This means the binary has been installed within the modules directory, all I need to do is define its inclusion within the php.ini file.

php56-redis module: php56-igbinary extension must be loaded manually within php.ini

I add one line statement right before the php56-redis module extension.

extension="/usr/local/opt/php56-igbinary/igbinary.so"

Restart apache, then everything just back to normal, like the good ol’ days.

WORKS