シェルスクリプトでいただくLinuxアプデ半自動化コマンド~プログラミング初心者を添えて~

# ごめんなさい
　これは[静岡大学ITソルーション室 Advent Calendar 2024](https://adventar.org/calendars/10607)20日目の記事です。20日目ということはつまり12月20日の担当なのですが、現在は12月29日。遅刻どころか既にクリスマスがアドベントしています。まぁ年末ですからきっと許してくれるはず。ということで元気にやっていきましょう。

# 作ったもの
https://github.com/Ottooooooo/apude-Command

　多くのLinuxにおいて標準的なアップデートの方法である`apt upgate`及び`apt upgrade`、`apt autoremove`の3つの手順を、**一発**のコマンドで、かつ**短い**コマンドで実行できるシェルスクリプトを書きました。
```
#!/bin/bash

echo "\n DO APT UPDATE \n"
sudo apt update
echo "\n UPDATE DONE! \n"
echo "\n DO APT UPGRADE -Y \n"
sudo apt upgrade -y
echo "\n DONE! \n"
echo "\n DO APT AUTOREMOVE - Y\n"
sudo apt autoremove -y
echo "\n DONE! \n"
echo "\n FINISHED!!!!!!!!!! \n"
```
↓実行するとこんな感じ↓
```
$ apude
DO APT UPDATE
[sudo] password for user:
...
DONE!


DO APT UPGRADE -Y
Reading package lists... Done
...
 DONE!


DO APT AUTOREMOVE - Y
Reading package lists... Done
...
DONE!


FINISHED!!

```
　また、これらを通常のコマンドのように使用するため、パスを通すなどしました。

# 作った理由
　情報学部といえば、技術者といえば、避けて通れないのがLinux。この記事を読んでくださっているみなさまも、きっと僕よりも日常的に使ってる方々ばかりでしょう。そんなLinuxで日常的に行う特徴的な作業のひとつとして、CUI操作によるアップデートがあります。
```
$ sudo apt update
Get:1 http://security.ubuntu.com/ubuntu jammy-security InRelease [129 kB]
...
$ sudo apt upgrade -y
Reading package lists... Done
...
$ sudo apt autoremove
Reading package lists... Done
...
```
　私が初めてLinuxを触った時に頼りにしていた記事には、初心者はこの操作から始めてみるよう書いてありました。「それっぽいかっけぇこと」が自分の手元で行えて感動したことを、今でも覚えています。
　...が、毎日のようにLinuxを触っていると、この操作が次第に面倒になってきました。一発で終わるならまだしもコマンドは３つで、しかも待機時間がとても中途半端。ただ待つには長いし、何か他の作業に移ろうとすると今度は時間が足りない。じゃあ一気に`sudo apt update && sudo apt upgrade -y && sudo apt autoremove`と打ってやればいいじゃないかと思うかもしれませんが、これはこれで面倒だと思います。そしてたまにうまくいかない(これはおま環やタイポに気づいてない可能性も高いけど)。

　そんな折、大学の授業内で「シェルスクリプト」に触れました。**これだ。**

# 作り方

### 1. ファイルを作る
　適当なところにディレクトリを作ってファイルを作ります。この**ファイル名がそのままコマンド名になる**ので命名には気を付けましょう。ディレクトリ名は関係ないので、ファイル名は超短くしてディレクトリ名で区別がつくようにするというのもいい方法ですね。驚いたことに拡張子は必要ないんだそう。
```
$ cd ~/codes
$ mkdir apude-Command
$ cd apude-Command
$ touch apude
```
　僕は自分の作ったものをすべて`~/codes/<name-of-directory>`に保管しています。

### 2. シェルスクリプトを書く
　作ったファイル内にこれを書きます。
```
#!/bin/bash

echo "\n DO APT UPDATE \n"
sudo apt update
echo "\n UPDATE DONE! \n"
echo "\n DO APT UPGRADE -Y \n"
sudo apt upgrade -y
echo "\n DONE! \n"
echo "\n DO APT AUTOREMOVE - Y\n"
sudo apt autoremove -y
echo "\n DONE! \n"
echo "\n FINISHED!!!!!!!!!! \n"
```
　シェルスクリプトは**コマンドラインに打ち込むときと同じ書き方で**書いてください。1行目の`#!/bin/bash`の意味は授業でも「おまじない」としか教わりませんでした。おれは弱い。
　`echo`はターミナルに何かを返すものです。`""`で囲めば文字列が扱えるのは他のプログラミング言語と変わりませんね。今回はこれを使うことで、今何をやっているのかがユーザに分かるようにしています。

### 3. パスを通す
　出たよこの言葉。僕は大学に入る前にプログラミングを軽く独学していた頃、この「パス」とかいう概念の理解に大変苦しめられた記憶があり、強い苦手意識を持っています。これを機にもう一回調べてみたけど正直今も分かってないです。嘘言ってたらごめんなさい。
　PATHというのは環境変数の一つです。環境変数というのは、システムと我々が勝手に書くコードとの媒介みたいな役割を果たしてくれるもので、コード内で定義しなくても使うことができます。逆に、コード内で環境変数と同じ名前の変数を作ることはできないようになっています。LinuxにおいてPATH変数は、コマンドが入力された時にそのコマンドに**対応する動作がどこに記されているか**、その**ファイルパスを収めてある変数**のようです。
　こんな説明で合ってんのかな？自信ね〜。
　すなわち、コマンドは「そのコマンドで**呼び起こされる動作を書いたファイルが存在する**」、「そのファイルの**パスがPATH変数に収められている**」、この2条件が揃ったとき、我々の望む振る舞いをしてくれるということになります。
まずは現在のPATHがどうなっているのか確認します。
```
echo $PATH
```
　なかなかの量が出力されると思いますが、ここに**1.で作ったディレクトリ**のパスが**無い**ことを確認してください。有ればこれ以降の操作は必要ありません。4まで飛ばしてください。無ければ、これから追加します。
シェルにも様々な種類があり、種類によってPATHのあるファイルは違うので、**使っているシェル**が何なのか調べます。
```
$ which $SHELL
```
　そしたらそのシェルに対応した設定ファイルを開きます。僕のシェルはbashだったので、`~/.bashrc`がそれです。よくわかんないけど、大概のシェルはなんとかrcが設定ファイルらしい。各自ググってもろて。
```
$ code ~/.bashrc
```
　コメントアウトされている箇所を読めば、どこがPATHに関わるのかは大体分かります。書き方もそれを真似するのが安全かなーと思います。僕は念には念を入れて、自分が勝手に書き加えた箇所であることがわかるようにコメントでメモ書きをしました。普段`~`で表現されるホームディレクトリが、ここに於いて`$HOME`と表現されることに注意ですね。
```
# my addition adding PATH
export PATH=$PATH:$HOME
# my addition ends
```

## 4. 実行権限を与える
　コマンドには実行権限というものがあり、これによって他ユーザの使用を許したり許さなかったり、root権限を求めたり求めなかったりが決まるそうです。皆さんの環境や想定している使用方法によって変わってきそう~~であると共に、僕はここでクソデカ大沼にハマり、色んな方法をやたらめったら試し、現時点でも「色々やったら動いた」程度の状態~~なので、**各自で調べる**ことを強くオススメします。
```
$ chmod 755 apude
```
　`apude`に入るのは各自で決めたコマンド名、すなわちファイル名です。

## 5. 動けば勝利
　実際にコマンドを入力してみてください。
```
$ apude
DO APT UPDATE
[sudo] password for user:
...
DONE!




DO APT UPGRADE -Y
Reading package lists... Done
...
 DONE!




DO APT AUTOREMOVE - Y
Reading package lists... Done
...
DONE!




FINISHED!!


```
　どのディレクトリ上で動かしても意図した動作をするならば、シェルスクリプトによる自作コマンドは無事完成です。お疲れ様でした。

# 考えたこと
### すまんそれ既製品でよくね？
　何も調べてないけど、上位互換的なスクリプトはどうせあるだろうなと思っています。ですが自分にとってのチュートリアルという側面が強いことから公開することに決めました。GitHubには成果物置き場としての使われ方だってありますもんね。

### 何らかの倫理に反していない？
　こーれ怖い。僕のような消費者に毛が生えたような人間は、アプデの度に`sudo apt update && sudo apt upgrade -y && sudo apt autoremove`とか打つのは正直めんどくせぇと思ってこれを作りました。ですが、もし動作を分けることが何らかの技術者思想において大切だったり、一個のコマンドで終わらせてしまうことが僕の知らないリスクを生んでしまったりしていたらどうしようかと。まあおいおい考えたいなと思ってます。

# 今後やりたいこと
### OSアプデをやれるオプション
`apt upgrade`の代わりに`apt full-upgrade`をやると、ディストロのバージョンを上げるレベルの大切なアップデートができるそうです。`-`付けるやつでこっちも選べるようにしたいなーと考えてます。

### ログを別の場所に流す
アレ普段からジロジロ見ることあります？僕はないですけど。別ファイルに出力できたら素敵だなと思います。何らかの倫理に触れてそう。でもそれを言ったらこのシェルスクリプト自体がそうなので。

# おわりに
　自分のやったことを記録として残すのは初めてのことなので、いろいろと粗さの残る部分があるかと思われます。お気づきの際はぜひ教えていただけると幸いです。
　ITソリューション室に入ることを決めて、室で僕よりも遥かに広い知見を持った先輩や同級生と関わることができて、とても幸せでした。順調に行けば来年は僕にも後輩ができます。今年いただいた身に余る恩を、少しずつでも後輩たちに還元したいと思います。自分のキャパを超えない程度に。
　ITソリューション室ではクリスマス直前にインフルエンザが流行しました。皆様もどうか体調には気を付けて、よい年末年始をお過ごしください。
**少し遅めのメリークリスマス。そしてよいお年を。**

............年内に書けてよかったぁ...