複数のユーザーでLinuxサーバーを共用する場合、個々のユーザーを効率良く管理することが重要です(図1)。ユーザーの一括登録、パスワード変更の義務付け、退社や退会などによるログイン自動停止などができると便利です。
そこ、Linuxサーバーにおけるユーザー管理方法を解説します。今回は、ユーザーの一括登録を紹介します。ここでも「Ubuntu 16.04 LTS」を例にします。
test
シェルスクリプトマガジン Vol.55のWeb掲載部分まとめです。
プレゼント&アンケートページはこちら!
シェルスクリプトマガジンvol.55は以下リンク先でご購入できます。
004 レポート テキストエディタ「Vim 8.1」公開
005 レポート トークイベント「TechLI ON」開催
006 NEWS FLASH
008 特集1 Linuxサーバー構築/麻生二郎 コード掲載
032 姐のNOGYO
033 特集2 IBM Cloud Functions を試す/小薗井康志、岸田吉弘、十川恵美、佐藤光太
048 特集3 GitHubの使い方/松浦隼人、水谷翔、鈴木順子
056 特別企画 仮想通貨マイニング/末安泰三 コード掲載
066 ラズパイ入門ボードで学ぶ電子回路の制御/米田聡 コード掲載
070 Node.js/Expressで楽々Webアプリ開発/しょっさん コード掲載
078 RESEARCHES FOR FUTURE/中村聡史
080 中小企業手作りIT化奮戦記 菅雄一
086 それプロのエバンジェリストから愛をこめて/山本美穂
088 漢のUNIX/後藤大地 コード掲載
098 人間とコンピュータの可能性/大岩元
100 バーティカルバーの極意/飯尾淳
106 法林浩之のFIGHTING TALKS/法林浩之
108 アジャイル開発 Let’s Practice!/熊野憲辰
112 機械学習のココロ/石井一夫
117 スズラボ通信/すずきひろのぶ
120 円滑コミュニケーションが世界を救う!/濱口誠
122 香川大学SLPからお届け!/山田昂平
128 ユニケージ新コードレビュー/伊藤和正 コード掲載
134 雲/桑原滝弥・イケヤシロウ
136 Techパズル/gori.sh
138 コラム「オールマイティーさを身に付けよう」/シェル魔人
Linuxやオープンソースに関連する技術者の需要が高まっています。特集1では、企業で人気のRed Hat Enterprise Linux(RHEL)のクローンOS「CentOS」による自宅サーバーの構築方法を解説しました。仮想化ソフト「Oracle VM VirtualBox」を用いてサーバーを構築しているので、Linux専用のパソコンやサーバー機を用意する必要はなく、気軽に始められます。
特集2では、米IBM社が提供する「IBM Cloud Functions」を扱いました、IBM Cloud Functionsは、最近話題のサーバーレス/マイクロサービスです。無料のアカウントを利用しての使い方、AIサービス「Watson」と組み合わせた実用的なアプリの作り方、導入事例を紹介しています。
特集3では、コードホスティングサービス「GitHub」のコラボレーション機能を中心に解説しました。また、そのほかの便利な機能もいくつか紹介しています。
特別企画は、仮想通貨のマイニング(採掘)です。専用のハードウエアを使うことなく、パソコンだけで採掘できる方法を紹介しました。
このほか、注目のサーバーサイド実行環境「Node.js」と「Express」フレームワークを活用するための新連載を開始しました。好評連載の「ラズパイ入門ボードで学ぶ電子回路の制御」では、OLEDへの画像表示を扱っています。シェルスクリプトマガジン特製の「ラズパイ入門ボード」を活用してください。
今月も読み応え十分のシェルスクリプトマガジン Vol.55。お見逃しなく!
著者:しょっさん
プログラミング言語「JavaScript」の実行環境「Node.js」と「Express」フレームワークを使って、基本となるWebアプリの開発手法を習得しましょう。第1回は「MVC」(Model View Controller)で「見た目」と「ロジック」を分離したWebアプリの開発手順を紹介します。
記事本文掲載のシェルスクリプトマガジンvol.55は以下のリンク先でご購入できます。
1 2 3 4 5 |
var indexRouter = require('./routes/index'); var usersRouter = require('./routes/users'); (略) app.use('/', indexRouter); app.use('/users', usersRouter); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
{ "name": "express-crud", "version": "0.0.0", "private": true, "scripts": { "start": "node ./bin/www" }, "dependencies": { "cookie-parser": "~1.4.3", "debug": "~2.6.9", "ejs": "~2.5.7", "express": "~4.16.0", "http-errors": "~1.6.2", "morgan": "~1.9.0", "pg": "^7.4.2", "sequelize": "^4.37.6", "sequelize-cli": "^4.0.0", "sqlite3": "^4.0.0" } } |
1 2 3 4 5 6 7 8 9 10 |
{ "development": { "dialect": "sqlite", "storage": ".db.development.sql" }, "production": { "use_env_variable": "DATABASE_URL" } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
// モデル情報の読み込み const models = require('../models'); // Expressルーターの記述 var express = require('express'); var router = express.Router(); // データを10件読み込んで、Web画面をレンダリングする router.get('/', function(req, res) { models.User.findAll({ order: [ ['id', 'desc'] ], limit: 10 }).then(function(users) { res.render('users', { title: 'Node.js/Express入門: CRUD サンプル', users: users }); }); }); // 新規追加ユーザーの作成 router.post('/create', function(req, res) { models.User.create({ first_name: req.body.first_name, last_name: req.body.last_name, email: req.body.email }).then(function() { res.redirect('/users'); }); }); // 対象IDのユーザー情報を更新 router.post('/update/:id', function(req, res) { models.User.update({ first_name: req.body.first_name, last_name: req.body.last_name, email: req.body.email }, { where: { id: req.params.id } }).then(function() { res.redirect('/users'); }); }); // 対象IDのユーザー情報を削除 router.get('/destroy/:id', function(req, res) { models.User.destroy({ where: { id: req.params.id } }).then(function() { res.redirect('/users'); }); }); // 外部から利用する場合の指定 module.exports = router; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<!DOCTYPE html> <html> <head> <title><%= title %></title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <h1><%= title %></h1> <form action="/users/create" method="post"> <label for="last_name">名前(姓): </label> <input id="last_name" type="text" name="last_name" value=""> <label for="first_name">名前(名): </label> <input id="first_name" type="text" name="first_name" value=""> <label for="email">メールアドレス: </label> <input id="email" type="text" name="email" value=""> <input type="submit" value="新規追加"> </form> <table> <tr> <th>ID</th> <th>名前(姓)</th> <th>名前(名)</th> <th>メールアドレス</th> <th></th> </tr> <% users.forEach(function (user) { %> <tr> <form action="/users/update/<%= user['id'] %>" method="post"> <td><%= user["id"] %></td> <td><input type="text" name="last_name" value="<%= user['last_name'] %>"></td> <td><input type="text" name="first_name" value="<%= user['first_name'] %>"></td> <td><input type="text" name="email" value="<%= user['email'] %>"></td> <td><input type="submit" value="更新"><a href="/users/destroy/<%= user['id'] %>">削除</a></td> </form> </tr> <% }); %> </table> </body> </html> |
著者:伊藤 和正
ユニケージでは、小さな道具の「コマンド」をシェルスクリプトで組み合わせて、さまざまな業務システムを構築しています。本連載では、毎回あるテーマに従ってユニケージによるシェルスクリプトの記述例を分かりやすく紹介します。第2回は、データを分割・保存した複数のテキストファイルの抽出や読み出しです。
記事本文掲載のシェルスクリプトマガジンvol.55は以下のリンク先でご購入できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
ERROR_CHECK(){ [ $(plus ${PIPESTATUS[@]}) -eq 0 ] && return echo "ERROR" exit 1 } echo * | tarr | ugrep -v '*' | xargs cat | (略) cat > $tmp-result ERROR_CHECK |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
(略) echo DATA/*/*/* | tarr | ugrep -v '*' | # 1:DATA/日付/店舗/商品 tr '/' ' ' | # 1:DATA 2:日付 3:店舗 4:商品 cjoin0 key=2 $tmp-days - | cjoin0 key=3 $tmp-tenpo - | cjoin0 key=4 $tmp-shohin - | tr ' ' '/' | # 1:DATA/日付/店舗/商品 xargs cat | (略) cat > $tmp-result ERROR_CHECK |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
(略) find DATA -type f | # 1:DATA/日付/店舗/商品 tr '/' ' ' | # 1:DATA 2:日付 3:店舗 4:商品 cjoin0 key=2 $tmp-days - | cjoin0 key=3 $tmp-tenpo - | cjoin0 key=4 $tmp-shohin - | tr ' ' '/' | # 1:DATA/日付/店舗/商品 xargs cat | (略) cat > $tmp-result ERROR_CHECK |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
loopx $tmp-day $tmp-tenpo $tmp-shohin | # 1:日付 2:店舗 3:商品 tr ' ' '/' | # 1:日付/店舗/商品 strcat \"DATA/\"+1 | # 1:DATA/日付/店舗/商品 xargs ls 2>/dev/null > $tmp-filepass cat $tmp-filepass | xargs cat | (略) cat > $tmp-result ERROR_CHECK |
著者:後藤 大地
C言語のJSON用ライブラリ「Jansson」の使い方を紹介する。Janssonライブラリは、使い方がかなり直感的で扱いやすい。C言語でJSONデータを扱いたいのなら最初に使っておきたいものだ。
記事本文掲載のシェルスクリプトマガジンvol.55は以下のリンク先でご購入できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
{ "Image": { "Width": 800, "Height": 600, "Title": "View from 15th Floor", "Thumbnail": { "Url": "http://www.example.com/image/481989943", "Height": 125, "Width": 100 }, "Animated" : false, "IDs": [116, 943, 234, 38793] } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
[ { "precision": "zip", "Latitude": 37.7668, "Longitude": -122.3959, "Address": "", "City": "SAN FRANCISCO", "State": "CA", "Zip": "94107", "Country": "US" }, { "precision": "zip", "Latitude": 37.371991, "Longitude": -122.026020, "Address": "", "City": "SUNNYVALE", "State": "CA", "Zip": "94085", "Country": "US" } ] |
1 |
{"Image":{"Width":800,"Height":600,"Title":"View from 15th Floor","Thumbnail":{"Url":"http://www.example.com/image/481989943","Height":125,"Width":100},"Animated":false,"IDs":[116,943,234,38793]}} |
1 |
[{"precision":"zip","Latitude":37.7668,"Longitude":-122.3959,"Address":"","City":"SAN FRANCISCO","State":"CA","Zip":"94107","Country":"US"},{"precision":"zip","Latitude":37.371991,"Longitude":-122.026020,"Address":"","City":"SUNNYVALE","State":"CA","Zip":"94085","Country":"US"}] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
#include <stdio.h> #include <stdlib.h> #include <jansson.h> void print_json_aux(json_t *element, int indent); const char *json_plural(int count) { return count == 1 ? "" : "s"; } void print_json_indent(int indent) { int i; for (i = 0; i < indent; i++) { putchar(' '); } } void print_json_object(json_t *element, int indent) { size_t size; const char *key; json_t *value; print_json_indent(indent); size = json_object_size(element); printf("JSON Object of %ld pair%s:\n", size, json_plural(size)); json_object_foreach(element, key, value) { print_json_indent(indent + 2); printf("JSON Key: \"%s\"\n", key); print_json_aux(value, indent + 2); } } void print_json_array(json_t *element, int indent) { size_t i; size_t size = json_array_size(element); print_json_indent(indent); printf("JSON Array of %ld element%s:\n", size, json_plural(size)); for (i = 0; i < size; i++) { print_json_aux(json_array_get(element, i), indent + 2); } } void print_json_string(json_t *element, int indent) { print_json_indent(indent); printf("JSON String: \"%s\"\n", json_string_value(element)); } void print_json_integer(json_t *element, int indent) { print_json_indent(indent); printf("JSON Integer: \"%" JSON_INTEGER_FORMAT "\"\n", json_integer_value(element)); } void print_json_real(json_t *element, int indent) { print_json_indent(indent); printf("JSON Real: %f\n", json_real_value(element)); } void print_json_true(json_t *element, int indent) { (void)element; print_json_indent(indent); printf("JSON True\n"); } void print_json_false(json_t *element, int indent) { (void)element; print_json_indent(indent); printf("JSON False\n"); } void print_json_null(json_t *element, int indent) { (void)element; print_json_indent(indent); printf("JSON Null\n"); } void print_json_aux(json_t *element, int indent) { switch (json_typeof(element)) { case JSON_OBJECT: print_json_object(element, indent); break; case JSON_ARRAY: print_json_array(element, indent); break; case JSON_STRING: print_json_string(element, indent); break; case JSON_INTEGER: print_json_integer(element, indent); break; case JSON_REAL: print_json_real(element, indent); break; case JSON_TRUE: print_json_true(element, indent); break; case JSON_FALSE: print_json_false(element, indent); break; case JSON_NULL: print_json_null(element, indent); break; default: fprintf(stderr, "unrecognized JSON type %d\n", json_typeof(element)); } } void print_json(json_t *root) { print_json_aux(root, 0); } json_t *load_json(const char *text) { json_t *root; json_error_t error; root = json_loads(text, 0, &error); if (root) { return root; } else { fprintf(stderr, "json error on line %d: %s\n", error.line, error.text); return (json_t *)0; } } char *read_line(char *line, int max_chars) { printf("Type some JSON > "); fflush(stdout); return fgets(line, max_chars, stdin); } int main(int argc, char *argv[]) { char line[4096]; if (argc != 1) { fprintf(stderr, "Usage: %s\n", argv[0]); exit(-1); } while (read_line(line, 4096) != (char *)NULL) { json_t *root = load_json(line); if (root) { print_json(root); json_decref(root); } } return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
#include <stdio.h> #include <stdlib.h> #include <jansson.h> int main(int argc, char *argv[]) { // JSONデータをパース json_error_t error; json_t *root = json_loads(buf, 0, &error); // JSON要素の種類判定 switch (json_typeof(root)) { case JSON_OBJECT: break; case JSON_ARRAY: break; case JSON_STRING: break; case JSON_INTEGER: break; case JSON_REAL: break; case JSON_TRUE: break; case JSON_FALSE: break; case JSON_NULL: break; default: } // JSONデータを印刷 printf("%s\n", json_string_value(element)); printf("%f\n", json_real_value(element)); printf("%lld\n", json_integer_value(element)); // 配列処理 int index; json_t *value; json_array_foreach(element, index, value) { printf("%d\n", index); ...value... } // オブジェクト処理 const char *key; json_t *value; json_object_foreach(element, key, value) { printf("%s\n", key); ...value... } // メモリー解放 json_decref(root); return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
#include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <jansson.h> void print(json_t *element, int indent) { const char *key; json_t *value; int index; #define INDENT \ for (int i = 0; i < indent; i++) \ putchar(' '); switch (json_typeof(element)) { case JSON_OBJECT: putchar('\n'); json_object_foreach(element, key, value) { INDENT printf("%s: ", key); print(value, 1+indent); } break; case JSON_ARRAY: putchar('\n'); json_array_foreach(element, index, value) { INDENT printf("%d: ", index); print(value, 1+indent); } break; case JSON_STRING: printf("%s\n", json_string_value(element)); break; case JSON_INTEGER: printf("%lld\n", json_integer_value(element)); break; case JSON_REAL: printf("%f\n", json_real_value(element)); break; case JSON_TRUE: printf("true\n"); break; case JSON_FALSE: printf("false\n"); break; case JSON_NULL: printf("null\n"); break; } } int main(int argc, char *argv[]) { char buf[1024 * 1024]; int fd = open(argv[1], O_RDONLY); read(fd, buf, 1024 * 1024 - 1); // JSONデータをパース json_error_t error; json_t *root = json_loads(buf, 0, &error); // JSONデータをトラバースしながら印刷 print(root, 0); // JSONメモリー解放 json_decref(root); close(fd); return 0; } |
著者:米田 聡
シェルスクリプトマガジンでは、小型コンピュータボード「Raspberry Pi」(ラズパイ)のプログラミングが楽しめる拡張ボード「ラズパイ入門ボード」を制作しました。本連載では、ラズパイ入門ボードを使った電子回路制御を取り上げていきます。第3回は、OLEDに画像を表示します。
記事本文掲載のシェルスクリプトマガジンvol.55は以下のリンク先でご購入できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#!/usr/bin/python3 # -*- coding: utf-8 -*- import time import Adafruit_GPIO.SPI as SPI import Adafruit_SSD1306 import RPi.GPIO as GPIO from PIL import Image from PIL import ImageDraw from PIL import ImageFont class EB_OLED(Adafruit_SSD1306.SSD1306_128_64): WIDTH = 128 HEIGHT = 64 __RST = 24 __DC = 23 SPI_PORT = 0 SPI_DEVICE = 0 def __init__(self): self.__spi = SPI.SpiDev(self.SPI_PORT, self.SPI_DEVICE, max_speed_hz=8000000) super().__init__(rst=self.__RST, dc=self.__DC, spi=self.__spi) if __name__ == "__main__": oled = EB_OLED() # 初期化 oled.begin() oled.clear() oled.display() jpg = Image.open("sample.jpg") # 画像を縮小 scale = float(float(EB_OLED.WIDTH)/float(jpg.size[0])) jpg = jpg.resize((int(jpg.size[0] * scale), int(jpg.size[1]*scale))) jpg = jpg.crop(box=(0, 0, EB_OLED.WIDTH, EB_OLED.HEIGHT)) # 2値に変換 image = jpg.convert('1') oled.image(image) oled.display() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
SW1=4 SW2=17 SW3=5 SW4=6 pos_y = 0 img_height = 0 f_exit = False jpg = None def sw_event(channel): global pos_y global f_exit global jpg global img_height if channel == SW1: if (img_height - pos_y - EB_OLED.HEIGHT) >= 0: pos_y += 1 elif channel == SW4: if pos_y <= 0: return pos_y -= 1 elif channel == SW2: f_exit = True image = jpg.crop(box=(0, pos_y, EB_OLED.WIDTH, EB_OLED.HEIGHT+pos_y)) oled.image(image) oled.display() if __name__ == "__main__": oled = EB_OLED() # OLED 初期化 oled.begin() oled.clear() oled.display() # スイッチ初期化 GPIO.setmode(GPIO.BCM) GPIO.setup([SW1, SW2, SW4], GPIO.IN) GPIO.add_event_detect(SW1, GPIO.FALLING, bouncetime=60) GPIO.add_event_detect(SW2, GPIO.FALLING, bouncetime=60) GPIO.add_event_detect(SW4, GPIO.FALLING, bouncetime=60) GPIO.add_event_callback(SW1, sw_event ) GPIO.add_event_callback(SW2, sw_event ) GPIO.add_event_callback(SW4, sw_event ) jpg = Image.open("sample.jpg") scale = float(float(EB_OLED.WIDTH)/float(jpg.size[0])) jpg = jpg.resize((int(jpg.size[0] * scale), int(jpg.size[1]*scale))) # 2値に変換 jpg = jpg.convert('1') img_height = jpg.size[1] image = jpg.crop(box=(0, 0, EB_OLED.WIDTH, EB_OLED.HEIGHT)) oled.image(image) oled.display() while f_exit == False: time.sleep(0.1) GPIO.cleanup() |
著者:末安 泰三
一時期のバブルは弾けた感じはありますが、仮想通貨にはまだまだ注目が集まっています。仮想通貨の一部は、パソコンでマイニング(採掘)という作業をすることで獲得できます。ASIC 耐性が高い「yescrypt」と呼ばれるハッシュ関数を使用する仮想通貨をマイニングする方法を紹介します。
記事本文掲載のシェルスクリプトマガジンvol.55は以下のリンク先でご購入できます。
1 2 3 4 5 6 7 8 9 |
#!/bin/sh if [ $# -ne 1 ];then echo "Usage: sh reqpkg.sh program" 1>&2 exit 1 fi apt-file update >/dev/null 2>&1 ldd $1 | grep "not found" | cut -d '=' -f 1 | tr -d [:blank:] | xargs -I {} apt-file -l search {} |
著者:麻生 二郎
CentOSやUbuntuなどのLinuxディストリビューション、パソコン、インターネットに接続する環境を用意すれば、無料で実用的なサーバーを構築できます。本特集では、企業のサーバーOSとして人気のCentOSを用いて、「ファイル共有」と「ブログ」の2種類のサーバーを立ち上げる方法を分かりやすく紹介します。
記事本文掲載のシェルスクリプトマガジンvol.55は以下のリンク先でご購入できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
TYPE="Ethernet" PROXY_METHOD="none" BROWSER_ONLY="no" BOOTPROTO="none" IPADDR="192.168.10.254" PREFIX="24" GATEWAY="192.168.10.1" DNS1="192.168.10.1" DEFROUTE="yes" IPV4_FAILURE_FATAL="no" IPV6INIT="yes" IPV6_AUTOCONF="yes" IPV6_DEFROUTE="yes" IPV6_FAILURE_FATAL="no" IPV6_ADDR_GEN_MODE="stable-privacy" NAME="enp0s3" UUID="120ac59c-2ec3-4ec4-b66f-2bcac2c8e18b" DEVICE="enp0s3" ONBOOT="yes" |
1 2 3 4 5 6 7 8 9 10 11 12 |
[global] workgroup = SHELLMAG dos charset = CP932 unix charset = UTF8 [share] comment = CentOS path = /var/share browsable = yes writable = yes create mask = 0777 directory mask = 0777 |
Linuxサーバー上で複数のユーザーが作業することもあります。通常、各ユーザーには、作業場所として「/home」ディレクトリーの下に自分の名前と同じ「ホームディレクトリー」が割り当てられています。自分のホームディレクトリー内なら自由にファイルを保存できます。
ただし、自由に保存できるからといって、一人のユーザーが多くのストレージ容量を使うと、システムや他の人が使用できる領域を圧迫しかねません。よって、ユーザーや、ユーザーが所属するグループごとにファイルシステム単位でストレージの使用容量を制限するための「クオータ」(Quota)機能が用意されています(図1)。そのクオータの設定方法を紹介します。今回も「Ubuntu Server 16.04 LTS」を例にします。
前回は、RAIDの運用管理における監視方法を紹介しました。RAIDの障害を検出したら、次の障害が発生する前に完全復旧させましょう。
完全復旧作業の手順は図1のようになります。
まず、障害が発生したストレージをRAIDアレイから切り離します。そして、サーバーマシンから故障したストレージを抜き取り、新しいストレージを交換します。「ホットスワップ」または「ホットプラグ」に対応したベイまたはケースなら電源を入れたまま抜き差しできますが、大抵はホットスワップに対応していません。サーバーマシンをシャットダウンして電源をオフにしてからストレージを交換してください。
交換を終えたら、サーバーマシンの電源をオンにします。サーバーが起動したら、新しいストレージに物理ボリュームを作成します。作成したら、RAIDアレイに追加します。これで完全復旧の完了です。
shell-mag ブログの 2018年7月 のアーカイブを表示しています。