※ パクレゼルヴではWeb開発エンジニアを大募集中!詳細はこちら

Archive

Archive for 2008/5

CSSとJavaScript No.1  

2008/5/28 水曜日 19:43:15

初めまして。

プログラマーではありませんが、参加させていただきました。

一応デザイナーの じゅんキチです。

初投稿です。宜しくお願いします。

中傷禁止であります!

CSSは素晴らしいですね。名前がかっこいい。

テーブル【いりません。】

SEO対策【やったー!!】

今日、初めて気付いたんですけど

<div style~>ってCSSなんですね。

中傷禁止であります!

今日はCSSを外部から読み込んでみました。

スッキリ!かっこいい!おもしろい!

ついでにJavaScriptも外部から読み込んでみました。

関数がうざいです。

こっちはまだまだ勉強が必要です。

そろそろFlashデコメも走りだしそうです。

こんな背景、デコメあったらいいな~って意見お待ちしております。

初なんでこのくらいで勘弁してやってください。

【また会いましょう!】

中傷禁止であります!

じゅんキチ HTMLとか

モバイル端末の判定[USER AGENT]  

2008/5/26 月曜日 20:14:48

のびーにょです。

今回は端末判定のプログラム。キャリアとか端末によって表示変えたいとか多々あると思いますので
携帯用ページを作成する場合必須と言っても過言ではないでしょう。
ってことで行ってみたいと思います。

/**
 * 機種情報取得(おおよその端末データ取得)
 * @auther のびー
 */
class MobileProfile{
	static $ins= null;
	// モバイルの情報
	var $ua;
	var $carrier;
	var $minor;
	var $width;
	var $height;
	var $htmltype;
	var $uid;
	//モバイルのプロフィール詳細
	var $id;
	var $device_name;
	var $name;
	var $maker;
	var $series;
	var $language;
	var $language_ver;
	var $browser_size;
	var $display_size;
	var $is_decome;
	var $decome_ver;
	var $connect_type;
	var $color;
	var $is_gif;
	var $is_jpg;
	var $is_png;
	var $camera;
	var $sub_camera;
	var $appli;
	var $appli_ver;
	var $appli_size;
	var $arrival_melody;
	var $is_arrival_music;
	var $is_arrival_full_music;
	var $is_arrival_movie;
	var $movie_type;
	var $flash;
	var $is_gps;
	var $is_ssl;
	var $mobile_customize;
	var $device_cash;
	var $release_date;
	var $modify_deta;
	var $mobileData;
	/**
	 * CONSTRUCTOR
	 */
	function MobileProfile()
	{
		self::$ins =& $this;
		self::$ins->setUa($_SERVER['HTTP_USER_AGENT']);
		self::$ins->carrierSet();
		self::$ins->setMobile();
	}
	/**
	 * 静的に呼び出された時に自身でインスタンスを取得する
	 */
	function getInstance(){
		if (null === self::$ins){
			new MobileProfile();
		}
	} 

	/**
	 * METHOD
	 */
	function carrierSet()
	{
		self::getInstance();
		self::$ins->ins->carrier = "";
		self::$ins->minor = ""; 

		switch(TRUE){
			//DOCOMO端末
			case (self::$ins->isDocomo()):
				self::$ins->setCarrier("DoCoMo");
			break;
			//SOFTBANK端末
			case (self::$ins->isSoftbank()):
				self::$ins->setCarrier("Softbank");
			break;
			//KDDI端末
			case (self::$ins->isEzweb()):
				self::$ins->setCarrier("au");
			break;
			//WILLCOM端末
			case (self::$ins->isWillcom()):
				self::$ins->setCarrier("WILLCOM");
			break;
			//googlebot判定
			case (self::$ins->isGooglebot()):
				self::$ins->setCarrier("GOOGLE");
			break;
			//i-robot判定
			case (self::$ins->isIrobot()):
				self::$ins->setCarrier("I-ROBOT");
			break;
			//検証用PC
			default:
				self::$ins->setCarrier('OTHER');
		}
	}
	/**
	 * 端末の詳細情報をセット
	 */
	function setMobile()
	{
		self::getInstance();
		switch(self::$ins->carrier){
			case ('DoCoMo'):
				preg_match("/^DoCoMo/[0-9.]{3}[ /]([^/( ]*)/",
								 self::$ins->ua,$ma);
				$deviceName = $ma[1];
				preg_match("/[(|/]c([0-9]{2,3})[)|;|/]/",
									self::$ins->ua."/",$ma);
				self::$ins->setDeviceCash($ma[1]*1000);
				//下位端末レベルのFOMAはMOVA扱い
				$lowar =
					 array("F2051"=>true,"N2051"=>true,
						"P2102V"=>true,"F2102V"=>true,
						"N2102V"=>true,"N2701"=>true,
						"NM850iG"=>true,"N2001"=>true,
						"N2002"=>true,"P2002"=>true,
						"D2101V"=>true,"P2101V"=>true,
						"SH2101V"=>true,"T2101V"=>true
					 );
				//MOVA(一部FOMA端末を含む)
				if(preg_match("/^DoCoMo/1.0/",self::$ins->ua) ||
				 isset($lowar[$deviceName])){
					self::$ins->setMinor('MOVA');
					if($ma[1] < '20'){
						self::$ins->setWidth(120);
						self::$ins->setHeight(180);
					}else{
						self::$ins->setWidth(200);
						self::$ins->setHeight(180);
					}
					self::$ins->setHtmlType("HTML");
					$buf = explode("/",self::$ins->ua);
					self::$ins->setDeviceName($buf[2]);
				//FOMA
				}else{
					self::$ins->setMinor('FOMA');
					self::$ins->setWidth(240);
					self::$ins->setHeight(320);
					self::$ins->setHtmlType("XHTML");
					self::$ins->setDeviceName($deviceName);
				}
			break;
			case('au'):
				//WAP1
				if (preg_match("/^UP.Browser/",
							 self::$ins->ua)) {
					self::$ins->setMinor('WAP1');
					self::$ins->setHtmlType("HTML");
				//WAP2
				}else{
					self::$ins->setMinor('WAP2');
					self::$ins->setHtmlType("XHTML");
				}
				if(isset(
						$_SERVER['HTTP_X_UP_DEVCAP_SCREENPIXELS'])){
					list($w,$h) = split(',',
						 $_SERVER['HTTP_X_UP_DEVCAP_SCREENPIXELS']);
				}else{
					$w = 96;
					$h = 96;
				}
				self::$ins->setWidth($w);
				self::$ins->setHeight($h);
				if(isset($_SERVER['HTTP_X_UP_DEVCAP_MAX_PDU'])){
					self::$ins->setDeviceCash(
					 $_SERVER['HTTP_X_UP_DEVCAP_MAX_PDU']);
				}else{
					self::$ins->setDeviceCash(200000);
				}
				$n = explode("-",self::$ins->ua);
				$device = explode(" ",$n[1]);
				self::$ins->setDeviceName($device[0]);
			break;
			case('Softbank'):
				if(preg_match("/^J-PHONE/2/",self::$ins->ua) ||
				 preg_match("/^J-PHONE/3/",self::$ins->ua)){
					//C型
					self::$ins->setMinor("TYPEC");
					self::$ins->setHtmlType("HTML");
					self::$ins->setDeviceCash(6000);
				}elseif(
						preg_match("/^J-PHONE/4/",self::$ins->ua)){
					//P型
					self::$ins->setMinor("TYPEP");
					self::$ins->setHtmlType("HTML");
					self::$ins->setDeviceCash(12000);
				}else if(
						preg_match("/^J-PHONE/5/",self::$ins->ua)){
					//W型
					self::$ins->setMinor("TYPEW");
					self::$ins->setHtmlType("XHTML");
					self::$ins->setDeviceCash(200000);
				}else if(preg_match("/^MOT-/",self::$ins->ua) ||
				 preg_match("/^Vodafone//",self::$ins->ua) ||
					preg_match("/^SoftBank//",self::$ins->ua)){
					//3GC型
					self::$ins->setMinor("3GC");
					self::$ins->setHtmlType("XHTML");
					self::$ins->setDeviceCash(300000);
				}
				if(isset($_SERVER['HTTP_X_JPHONE_DISPLAY'])){
					list($w,$h) =
								split('*',
									$_SERVER['HTTP_X_JPHONE_DISPLAY']);
				}else{
					$w = 96;
					$h = 96;
				}
				self::$ins->setWidth($w);
				self::$ins->setHeight($h);
				if(isset($_SERVER['HTTP_X_JPHONE_MSNAME'])){
					self::$ins->setDeviceName(
							$_SERVER['HTTP_X_JPHONE_MSNAME']);
				}else{
					self::$ins->setDeviceName("");
				}
			break;
			case('OTHER'):
				self::$ins->setMinor("PC");
				self::$ins->setWidth(240);
				self::$ins->setHeight(320);
				self::$ins->setHtmlType("XHTML");
				self::$ins->setDeviceCash(99999999);
				$pc =
				 (isset($_REQUEST['pc']))?$_REQUEST['pc']:"";
				self::$ins->setDeviceName("PC");
			break;
		}
	} 

	/**
	 * 端末詳細データ取得(共通管理ファイルより)
	 * @param	String	device_name		端末ID
	 */
	function getMobileDetail($device_name=null)
	{
		self::getInstance();
		if(!$device_name){
			$device_name = self::$ins->device_name;
		}
		$dirfile = __FILE__;
		$dir_name =
						str_replace(basename(__FILE__),'',$dirfile);
		$dir_name .= 'MobileProfileData/';
		$carrier = self::$ins->carrier;
		$carrier = strtolower($carrier);
		//データ配列読み込み
		if(file_exists($dir_name.$carrier.'Data.php')){
			require_once $dir_name.$carrier.'Data.php';
			if(!$this->mobileData){
				$this->mobileData = $modile_detail;
			}
		}else{
			return FALSE;
		}
		if(isset($this->mobileData[$device_name])){
			foreach(
				 $this->mobileData[$device_name] as
								$key => $val){
				self::$ins->{$key} = $val;
			}
			if(isset(self::$ins->display_size)){
				list(self::$ins->height,self::$ins->width) =
				 explode('*',self::$ins->display_size);
			}
			return $this->mobileData[$device_name];
			//TODO
			//すでにセットしてあるプロパティの値を上書き 

		}else{
			return FALSE;
		}
	} 

	/**
	 * 公式UIDの取得
	 */
	function getPublicUid()
	{
		self::getInstance();
		$uid = '';
		switch(self::$ins->carrier){
			case('DOCOMO'):
    //CPの守秘義務に引っかかるかもなので消しときます
			break;
			case('EZWEB'):
    //CPの守秘義務に引っかかるかもなので消しときます
			break;
			case('SOFTBANK'):
    //CPの守秘義務に引っかかるかもなので消しときます
			break;
			default :
				$uid = TESTUID; //定数で適当なUIDを定義
			break;
		}
		return $uid;
	} 

	/**
	 * 非公式UTN取得
	 *
	 */
	function getNotPublicUid()
	{
		$uid = FALSE;
		switch(self::$ins->carrier){
			case('DOCOMO'):
				//FOMAの場合はFOMAカード識別番号を使う
				if(ereg("DoCoMo/2.0.*;icc(.*))$",
							self::$ins->ua,$regs1) == TRUE){
					$uid = $regs1[1];
				}elseif(ereg("DoCoMo/1.0/.*ser(.*)$",
							self::$ins->ua,$regs2) == TRUE){
					//movaの場合は端末製造番号を使う
					$uid = $regs2[1];
				}
			break;
			case('EZWEB'):
				if(isset($_SERVER['HTTP_X_UP_SUBNO'])){
					$uid = $_SERVER['HTTP_X_UP_SUBNO'];
				}
			break;
			case('SOFTBANK'):
				if(isset($_SERVER['HTTP_X_JPHONE_UID'])){
					$uid =
						substr($_SERVER['HTTP_X_JPHONE_UID'],1);
				}elseif(isset($_SERVER["x-jphone-uid"])){
					$uid = $_SERVER["x-jphone-uid"];
				}
			break;
			default :
				$uid = 'TESTUID';
			break;
		}
		return $uid;
	}
	/**
	 * キャリア判定(DOCOMO)
	 */
	function isDocomo()
	{
		if(preg_match("/^DoCoMo/",self::$ins->ua)){
			return TRUE;
		}else{
			return FALSE;
		}
	}
	/**
	 * キャリア判定(SOFTBANK)
	 */
	function isSoftbank()
	{
		if(preg_match("/^J-PHONE/",self::$ins->ua) ||
		 preg_match("/^MOT-/",self::$ins->ua) ||
			preg_match("/^Vodafone//",self::$ins->ua) ||
			 preg_match("/^SoftBank//",self::$ins->ua)){
			return TRUE;
		}else{
			return FALSE;
		}
	}
	/**
	 * キャリア判定(EZWEB)
	 */
	function isEzweb()
	{
		if(preg_match("/^UP.Browser/",self::$ins->ua) ||
		 preg_match("/^KDDI/",self::$ins->ua)){
			return TRUE;
		}else{
			return FALSE;
		}
	}
	/**
	 * キャリア判定(WILLCOM)
	 */
	function isWillcom()
	{
		return FALSE;
	}
	/**
	 * キャリア判定(GOOGLEBOT)
	 */
	function isGooglebot()
	{
		return FALSE;
	} 

	function isIrobot()
	{
		return FALSE;
	}
	/**
	 * SETTER
	 */
	function setDeviceName($arg)
	{
		self::$ins->device_name = $arg;
	}
	function setHtmlType($arg)
	{
		self::$ins->htmltype = $arg;
	} 

	function setUa($arg)
	{
		self::$ins->ua = $arg;
	}
	function setUid($arg)
	{
		self::$ins->uid = $arg;
	} 

	function setDeviceCash($arg)
	{
		self::$ins->device_cash = $arg;
	}
	function setWidth($arg)
	{
		self::$ins->width = $arg;
	}
	function setHeight($arg)
	{
		self::$ins->height = $arg;
	}
	function setMinor($arg)
	{
		self::$ins->minor = $arg;
	}
	function setCarrier($arg)
	{
		self::$ins->carrier = $arg;
	}
	/**
	 * GETTER
	 */
	//自由に取得できるgeter
	function get($arg)
	{
		self::getInstance();
		if(!$arg){
			return FALSE;
		}
		$ret = FALSE;
		if(is_array($arg)){
			foreach($arg as $val){
				if(isset(self::$ins->{$val})){
					$ret[$val] = self::$ins->{$val};
				}
			}
		}else{
			if(isset(self::$ins->{$arg})){
				$ret = self::$ins->{$arg};
			}else{
				return FALSE;
			}
		}
		return $ret;
	}
}

長いですねぇ・・・
検索エンジン回りが常にFALSEなのはわざとです。
後、WILLCOMも未対応です。(サイトまだ作ってないので放置です)

クラスと同一ディレクトリ内に
『MobileProfileData』
ってディレクトリを作成して
その中に
auData.php   ←au用の端末詳細情報配列
docomoData.php ←ドコモ用
otherData.php  ←全キャリア用
softbankData.php←ソフトバンク用
って各ファイルを作成
ファイルの中身は

'SH904i' => array('id' => '395',
				'device_name' => 'SH904i',
				'name' => 'SH904i',
				'carrier' => 'DoCoMo',
				'maker' => 'SHARP',
				'series' => 'FOMA904i',
				'language' => 'XHTML',
				'language_ver' => '2.1',
				'browser_size' => '320*240',
				'display_size' => '400*240',
				'is_decome' => 'YES',
				'decome_ver' => '3',
				'connect_type' => 'WCDMA',
				'color' => '262144',
				'is_gif' => 'YES',
				'is_jpg' => 'YES',
				'is_png' => 'NO',
				'camera' => '320',
				'sub_camera' => '11',
				'appli' => 'Java',
				'appli_ver' => '5',
				'appli_size' => '1024',
				'arrival_melody' => '128',
				'is_arrival_music' => 'YES',
				'is_arrival_full_music' => 'YES',
				'is_arrival_movie' => 'YES',
				'movie_type' => '3gp',
				'flash' => 'FL1.1',
				'is_gps' => 'YES',
				'is_ssl' => 'YES',
				'mobile_customize' => '',
				'device_cash' => '102400',
				'release_date' => '2007-05-25 00:00:00',
				'modify_deta' => '0000-00-00 00:00:00',
				),・・・

って配列が大量に並んでます。

ちなみに弊社ではこの配列はDBで保存して端末が発売されるたびに更新かけてます
バッチ組んで各キャリアごとの上記ファイルを生成。
配列が大きすぎるとか思うなら世代ごとにさらに詳細にファイル分割してやればすむかなぁと思ってますよ。

んで、使い方
超簡単

//newしてやって(この時点で大雑把な一般的な数値が取得可能)
$LIB_MP = new MobileProfile();
//端末名称取得
$device_name = $LIB_MP->get("device_name");
//PCからのアクセスの場合、
//もしくは端末名が取れなかった場合(登録漏れ等)
if($device_name == 'PC' || $device_name == FALSE){
  //SH904用の端末情報を取得する
  $device_name = 'SH904i';
}
//で、詳細情報取得
$LIB_ARR_MP = $LIB_MP->getMobileDetail($device_name);
//とりあえず出力してみる
if($LIB_ARR_MP){
  foreach($LIB_ARR_MP as $key => $val){
    $str .= $key,":".$val."n";
  }
}

上記をやってやれば

id :395
device_name :SH904i
name :SH904i
carrier :DoCoMo
maker :SHARP
series :FOMA904i
language :XHTML
language_ver :2.1
browser_size :320*240
display_size :400*240
is_decome :YES
decome_ver :3
connect_type :WCDMA
color :262144
is_gif :YES
is_jpg :YES
is_png :NO
camera :320
sub_camera :11
appli :Java
appli_ver :5
appli_size :1024
arrival_melody :128
is_arrival_music :YES
is_arrival_full_music:YES
is_arrival_movie :YES
movie_type :3gp
flash :FL1.1
is_gps :YES
is_ssl :YES
mobile_customize :
device_cash :102400
release_date :2007-05-2500:00:00
modify_deta :0000-00-0000:00:00

というような実行結果が得られると思います。

ってことで上記方法で端末判定行ってます。
DBさえ作ってしまえば端末発売毎の登録の煩わしさだけで済むので
普段の対応考えると管理画面を作っちゃえば割りと楽です。

PEAR::Net_UserAgent_Mobileなんかもありますが
端末情報がベタ書きな上に情報が足りない部分が多々あるので
自作クラスで対応しています。

後更新してないみたいですし。

0.31.0 2008-02-10 beta
↑この間1年更新がなかった(自分で端末情報更新してもいいと思いますけどね)
0.30.0 2007-02-20 beta
0.29.0 2006-11-07 beta
0.28.0 2006-09-25 beta
0.27.0 2006-07-13 beta
0.26.0 2006-02-01 beta

最近RC1が出たみたいですけどね

端末情報は色々な企業さんが販売してますね。
今までに発売した端末情報すべてとか。
買い切りだと4,5万だと思うので、携帯サイトをがっつりやる場合は買って損はないと思います。
後は発売される度に管理画面から追加って形取ればそこまでめんどくさくないですし。

公式CP(IP)やってると詳細情報を手に入れることができるのでそのデータを自社内だけだと存分に活用できるのも含めて
自社オリジナルクラス使ってます。

色々なやり方あるとは思いますが、弊社の一部のコンテンツはこんな感じで運用しております

のびーにょ PHP, キャリア, 携帯電話

メール配信  

2008/5/16 金曜日 18:08:10

暑かったり寒かったり雨が降ったり降らなかったり。

皆様いかがお過ごしでしょうか。こんにちわ。かーつんです。

さてさて、今回はなにを書こうか悩んでいたのですが、

良いネタが見つからなかったので、直近のお仕事の様子でも少々。

現在、会員様向けにメール配信を行う用のスクリプトを作ってるんですが、

色々と難航しております。

3つのサーバから1つのDB参照して、同時稼働。

なんか昔バッチ組んでるときに似たようなことしたなぁと思いながら、

正直覚えて無くて、超抜けまくり。

のびーにょ先生に怒られツッコまれながら四苦八苦しております。

で、気をつけるべき点で、残しておきたいと思ったことを以下に記しておきます。

1.コネクション数・SQL発行回数を極限まで減らして一括でデータ取得すると、

  同時稼働している3つのサーバに同じデータが取得される可能性がある。

  ⇒回避策⇒

   データテーブルとは別にカウント用のテーブルをテンポラリとして作成して、

   取得した件数をそっちに残しておけば、

   サーバジョブ起動タイミングを少しずらすだけで異なるデータを一括取得できる。

   但し、ジョブを途中で中断したときにデータに不整合が起こるので、

   回避策が更に必要。(´・д・`)

2.MySQLはUPDATEの対象テーブルと、

  WHERE句で使用するSELECT(サブクエリ)の対象テーブルが同じだと、

ERROR 1093 (HY000): You can't specify target table ・・・

  とかって怒る。

  ⇒回避策⇒

   素直にSQL分けるか、DB変える。

   MySQLは少し面倒な処理をさせようとすると、すぐ怒る。。。

   Oracleなどは怒られないのにネ・・・。

3.メールが送れなかった場合の処理が必要なら、

  メールヘッダのReturn-Pathにエラーメールを送って欲しいアドレスを記載する。

  ⇒具体的には⇒

mb_send_mail('送信先メールアドレス','タイトル','本文',
	メールヘッダ(送信元アドレスとか文字コードとか),
	'ヘッダオプション');

⇒⇒⇒ Return-Pathはヘッダオプションに、
‘-f エラーメールを受信したいアドレス’
を書くとよし。

mb_send_mail("hogehoge@hoge.jp","タイトル","本文",
	"FROM:hogetyo@hoge.jp \n
	Content-Type: text/plain; charset=ISO-2022-JP",
	"-f hoge-error@hoge.jp");

  こんな感じ。

4.送信間隔を考えないと、携帯キャリアからスパム扱いされる。

  ⇒回避策⇒

   ん~模索中。リアルタイムで調整できると一番良いんだけど・・・。(´・д・`)

と、まぁ、こんなとこでしょうか。

他にも色々あったような気がするけど、

自身で理解し切れてないことが多いので、

またの機会と言うことで。

でわ、おばかーつんがおおくりしました。

かーつん Linux, MySQL, PHP, 携帯電話

若いもんたちにより生み出されるSjis文字対応  

2008/5/16 金曜日 17:51:22

こんばんわ、ボクです。

最近の若いもんはギャル文字とか、①②とかいうSjis文字をよく使います。
後者の文字はSjisじゃないDBでは文字化けてしまいます。
対策としては、DBをSjisにするか、適当な代用文字に置き換えるくらいですかの。
前者は大人の事情なので無理な場合もあるので、後者を実装。

①~⑲のAsciiコードは8740~8759ですので、これらをDBに突っ込む前に置き換えます。

$buf = pack("H*", 文字);

文字を、パックしてあげ、該当するものを置き換えてあげます。
そして、出力するときに、replaceかなにかで戻してあげます。

これで、とりあえずは出力できるはず。

めも。

isset()

if (isset($aaa) && isset($bbb)){}

 ↓

if (isset($aaa, $bbb)){}

isset()関数は一度に複数の値を指定できるようです。
値はすべてAND条件になりますが…

下音タヌキ PHP, Tips

サーバいじってみました。  

2008/5/15 木曜日 19:58:12

はーい!べきこです。

開発担当だったはずなのに、最近お仕事でサーバを少々いじっております(´ー`)

私、コンソールで操作するのちょっと苦手です。(チョット?^^)
単純な内容表示系コマンドならいいんですけど、
ファイルの中身いじったりとか、そもそも大事なファイルがいっぱいあるので非常に怖いのです・・

OSのインストール~関連ソフトのインストール、設定作業をちょこちょこやらせてもらっているのですが、
初めての課題が!!!
姜子牙せんせー「IPアドレスとホスト名を××に変更しておいてね☆」
べきこ「(>Д<)ゝ」

あわわ(゚Д゚;)

とりあえず、調べる。
なんだかひとつの場所いじればいいってものじゃないんですね。。

とりあえず変更したのはこの3つ(私の使用している環境はCentOSです)
・/etc/hosts

127.0.0.1 localhost.localdomain localhost
192.168.*.* svr_test_01

・/etc/sysconfig/network

NETWORKING=yes
NETWORKING_IPV6=yes
HOSTNAME=svr_test_01
GATEWAY=192.168.0.1

・/etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE=eth0
BOOTPROTO=static
DHCPCLASS=
HWADDR=00:13:72:AD:5B:45
IPADDR=192.168.*.*
NETMASK=255.255.255.0
ONBOOT=yes

かなりドキドキしながら変更処理。
編集にはviエディタを使いました。ちゃんと使いこなせるようにしたいなぁ・・

基本的には対応の名前(HOSTNAMEとか)が記述されてるのでわかりやすいですね。
OSインストールの時点ですでに決まっている値に関しては、設定済みなので数はそんなにないと思うのですが・・・
どうしても緊張してしまう・・・もう少し数をこなさないといけませんね。

せっかく普段と違う部分にふれる機会なのでいろいろ吸収していきたいですね!
それでは今日はここまで!

べきこ Linux, Tips