2808 lines
239 KiB
HTML
2808 lines
239 KiB
HTML
|
<!DOCTYPE html><html lang="fr">
|
|||
|
<head><meta charset="utf-8">
|
|||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|||
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"><title>MULTIBOOT USB 32Go (EFI+GPT et BIOS+GPT/MBR) - YannStatic</title>
|
|||
|
|
|||
|
<meta name="description" content="Un lecteur USB multiboot permettant de démarrer plusieurs fichiers ISO Archlinux, Debian, Manjaro, PartedMagic, Tails, etc…">
|
|||
|
<link rel="canonical" href="https://static.rnmkcy.eu/2020/03/10/GRUB-files-and-scripts-for-create-usb-pendrive-capable-of-booting-different-ISO-files(multiboot).html"><link rel="alternate" type="application/rss+xml" title="YannStatic" href="/feed.xml">
|
|||
|
|
|||
|
<!-- - include head/favicon.html - -->
|
|||
|
<link rel="shortcut icon" type="image/png" href="/assets/favicon/favicon.png"><link rel="stylesheet" href="/assets/css/main.css"><link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" ><!-- start custom head snippets --><link rel="stylesheet" href="/assets/css/expand.css">
|
|||
|
<!-- end custom head snippets --><script>(function() {
|
|||
|
window.isArray = function(val) {
|
|||
|
return Object.prototype.toString.call(val) === '[object Array]';
|
|||
|
};
|
|||
|
window.isString = function(val) {
|
|||
|
return typeof val === 'string';
|
|||
|
};
|
|||
|
|
|||
|
window.hasEvent = function(event) {
|
|||
|
return 'on'.concat(event) in window.document;
|
|||
|
};
|
|||
|
|
|||
|
window.isOverallScroller = function(node) {
|
|||
|
return node === document.documentElement || node === document.body || node === window;
|
|||
|
};
|
|||
|
|
|||
|
window.isFormElement = function(node) {
|
|||
|
var tagName = node.tagName;
|
|||
|
return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA';
|
|||
|
};
|
|||
|
|
|||
|
window.pageLoad = (function () {
|
|||
|
var loaded = false, cbs = [];
|
|||
|
window.addEventListener('load', function () {
|
|||
|
var i;
|
|||
|
loaded = true;
|
|||
|
if (cbs.length > 0) {
|
|||
|
for (i = 0; i < cbs.length; i++) {
|
|||
|
cbs[i]();
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
return {
|
|||
|
then: function(cb) {
|
|||
|
cb && (loaded ? cb() : (cbs.push(cb)));
|
|||
|
}
|
|||
|
};
|
|||
|
})();
|
|||
|
})();
|
|||
|
(function() {
|
|||
|
window.throttle = function(func, wait) {
|
|||
|
var args, result, thisArg, timeoutId, lastCalled = 0;
|
|||
|
|
|||
|
function trailingCall() {
|
|||
|
lastCalled = new Date;
|
|||
|
timeoutId = null;
|
|||
|
result = func.apply(thisArg, args);
|
|||
|
}
|
|||
|
return function() {
|
|||
|
var now = new Date,
|
|||
|
remaining = wait - (now - lastCalled);
|
|||
|
|
|||
|
args = arguments;
|
|||
|
thisArg = this;
|
|||
|
|
|||
|
if (remaining <= 0) {
|
|||
|
clearTimeout(timeoutId);
|
|||
|
timeoutId = null;
|
|||
|
lastCalled = now;
|
|||
|
result = func.apply(thisArg, args);
|
|||
|
} else if (!timeoutId) {
|
|||
|
timeoutId = setTimeout(trailingCall, remaining);
|
|||
|
}
|
|||
|
return result;
|
|||
|
};
|
|||
|
};
|
|||
|
})();
|
|||
|
(function() {
|
|||
|
var Set = (function() {
|
|||
|
var add = function(item) {
|
|||
|
var i, data = this._data;
|
|||
|
for (i = 0; i < data.length; i++) {
|
|||
|
if (data[i] === item) {
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
this.size ++;
|
|||
|
data.push(item);
|
|||
|
return data;
|
|||
|
};
|
|||
|
|
|||
|
var Set = function(data) {
|
|||
|
this.size = 0;
|
|||
|
this._data = [];
|
|||
|
var i;
|
|||
|
if (data.length > 0) {
|
|||
|
for (i = 0; i < data.length; i++) {
|
|||
|
add.call(this, data[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
Set.prototype.add = add;
|
|||
|
Set.prototype.get = function(index) { return this._data[index]; };
|
|||
|
Set.prototype.has = function(item) {
|
|||
|
var i, data = this._data;
|
|||
|
for (i = 0; i < data.length; i++) {
|
|||
|
if (this.get(i) === item) {
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
};
|
|||
|
Set.prototype.is = function(map) {
|
|||
|
if (map._data.length !== this._data.length) { return false; }
|
|||
|
var i, j, flag, tData = this._data, mData = map._data;
|
|||
|
for (i = 0; i < tData.length; i++) {
|
|||
|
for (flag = false, j = 0; j < mData.length; j++) {
|
|||
|
if (tData[i] === mData[j]) {
|
|||
|
flag = true;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if (!flag) { return false; }
|
|||
|
}
|
|||
|
return true;
|
|||
|
};
|
|||
|
Set.prototype.values = function() {
|
|||
|
return this._data;
|
|||
|
};
|
|||
|
return Set;
|
|||
|
})();
|
|||
|
|
|||
|
window.Lazyload = (function(doc) {
|
|||
|
var queue = {js: [], css: []}, sources = {js: {}, css: {}}, context = this;
|
|||
|
var createNode = function(name, attrs) {
|
|||
|
var node = doc.createElement(name), attr;
|
|||
|
for (attr in attrs) {
|
|||
|
if (attrs.hasOwnProperty(attr)) {
|
|||
|
node.setAttribute(attr, attrs[attr]);
|
|||
|
}
|
|||
|
}
|
|||
|
return node;
|
|||
|
};
|
|||
|
var end = function(type, url) {
|
|||
|
var s, q, qi, cbs, i, j, cur, val, flag;
|
|||
|
if (type === 'js' || type ==='css') {
|
|||
|
s = sources[type], q = queue[type];
|
|||
|
s[url] = true;
|
|||
|
for (i = 0; i < q.length; i++) {
|
|||
|
cur = q[i];
|
|||
|
if (cur.urls.has(url)) {
|
|||
|
qi = cur, val = qi.urls.values();
|
|||
|
qi && (cbs = qi.callbacks);
|
|||
|
for (flag = true, j = 0; j < val.length; j++) {
|
|||
|
cur = val[j];
|
|||
|
if (!s[cur]) {
|
|||
|
flag = false;
|
|||
|
}
|
|||
|
}
|
|||
|
if (flag && cbs && cbs.length > 0) {
|
|||
|
for (j = 0; j < cbs.length; j++) {
|
|||
|
cbs[j].call(context);
|
|||
|
}
|
|||
|
qi.load = true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
var load = function(type, urls, callback) {
|
|||
|
var s, q, qi, node, i, cur,
|
|||
|
_urls = typeof urls === 'string' ? new Set([urls]) : new Set(urls), val, url;
|
|||
|
if (type === 'js' || type ==='css') {
|
|||
|
s = sources[type], q = queue[type];
|
|||
|
for (i = 0; i < q.length; i++) {
|
|||
|
cur = q[i];
|
|||
|
if (_urls.is(cur.urls)) {
|
|||
|
qi = cur;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
val = _urls.values();
|
|||
|
if (qi) {
|
|||
|
callback && (qi.load || qi.callbacks.push(callback));
|
|||
|
callback && (qi.load && callback());
|
|||
|
} else {
|
|||
|
q.push({
|
|||
|
urls: _urls,
|
|||
|
callbacks: callback ? [callback] : [],
|
|||
|
load: false
|
|||
|
});
|
|||
|
for (i = 0; i < val.length; i++) {
|
|||
|
node = null, url = val[i];
|
|||
|
if (s[url] === undefined) {
|
|||
|
(type === 'js' ) && (node = createNode('script', { src: url }));
|
|||
|
(type === 'css') && (node = createNode('link', { rel: 'stylesheet', href: url }));
|
|||
|
if (node) {
|
|||
|
node.onload = (function(type, url) {
|
|||
|
return function() {
|
|||
|
end(type, url);
|
|||
|
};
|
|||
|
})(type, url);
|
|||
|
(doc.head || doc.body).appendChild(node);
|
|||
|
s[url] = false;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
return {
|
|||
|
js: function(url, callback) {
|
|||
|
load('js', url, callback);
|
|||
|
},
|
|||
|
css: function(url, callback) {
|
|||
|
load('css', url, callback);
|
|||
|
}
|
|||
|
};
|
|||
|
})(this.document);
|
|||
|
})();
|
|||
|
</script><script>
|
|||
|
(function() {
|
|||
|
var TEXT_VARIABLES = {
|
|||
|
version: '2.2.6',
|
|||
|
sources: {
|
|||
|
font_awesome: 'https://use.fontawesome.com/releases/v5.0.13/css/all.css',
|
|||
|
jquery: '/assets/js/jquery.min.js',
|
|||
|
leancloud_js_sdk: '//cdn.jsdelivr.net/npm/leancloud-storage@3.13.2/dist/av-min.js',
|
|||
|
chart: 'https://cdn.bootcss.com/Chart.js/2.7.2/Chart.bundle.min.js',
|
|||
|
gitalk: {
|
|||
|
js: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.js',
|
|||
|
css: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.css'
|
|||
|
},
|
|||
|
valine: 'https://unpkg.com/valine/dist/Valine.min.js'
|
|||
|
},
|
|||
|
site: {
|
|||
|
toc: {
|
|||
|
selectors: 'h1,h2,h3'
|
|||
|
}
|
|||
|
},
|
|||
|
paths: {
|
|||
|
search_js: '/assets/search.js'
|
|||
|
}
|
|||
|
};
|
|||
|
window.TEXT_VARIABLES = TEXT_VARIABLES;
|
|||
|
})();
|
|||
|
</script>
|
|||
|
</head>
|
|||
|
<body>
|
|||
|
<div class="root" data-is-touch="false">
|
|||
|
<div class="layout--page js-page-root"><!----><div class="page__main js-page-main page__viewport hide-footer has-aside has-aside cell cell--auto">
|
|||
|
|
|||
|
<div class="page__main-inner"><div class="page__header d-print-none"><header class="header"><div class="main">
|
|||
|
<div class="header__title">
|
|||
|
<div class="header__brand"><svg id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="478.9473684210526" viewBox="0, 0, 400,478.9473684210526"><g id="svgg"><path id="path0" d="M308.400 56.805 C 306.970 56.966,303.280 57.385,300.200 57.738 C 290.906 58.803,278.299 59.676,269.200 59.887 L 260.600 60.085 259.400 61.171 C 258.010 62.428,256.198 63.600,255.645 63.600 C 255.070 63.600,252.887 65.897,252.598 66.806 C 252.460 67.243,252.206 67.600,252.034 67.600 C 251.397 67.600,247.206 71.509,247.202 72.107 C 247.201 72.275,246.390 73.190,245.400 74.138 C 243.961 75.517,243.598 76.137,243.592 77.231 C 243.579 79.293,241.785 83.966,240.470 85.364 C 239.176 86.740,238.522 88.365,237.991 91.521 C 237.631 93.665,236.114 97.200,235.554 97.200 C 234.938 97.200,232.737 102.354,232.450 104.472 C 232.158 106.625,230.879 109.226,229.535 110.400 C 228.933 110.926,228.171 113.162,226.434 119.500 C 226.178 120.435,225.795 121.200,225.584 121.200 C 225.373 121.200,225.200 121.476,225.200 121.813 C 225.200 122.149,224.885 122.541,224.500 122.683 C 223.606 123.013,223.214 123.593,223.204 124.600 C 223.183 126.555,220.763 132.911,219.410 134.562 C 218.443 135.742,217.876 136.956,217.599 138.440 C 217.041 141.424,215.177 146.434,214.532 146.681 C 214.240 146.794,214.000 147.055,214.000 147.261 C 214.000 147.467,213.550 148.086,213.000 148.636 C 212.450 149.186,212.000 149.893,212.000 150.208 C 212.000 151.386,208.441 154.450,207.597 153.998 C 206.319 153.315,204.913 150.379,204.633 147.811 C 204.365 145.357,202.848 142.147,201.759 141.729 C 200.967 141.425,199.200 137.451,199.200 135.974 C 199.200 134.629,198.435 133.224,196.660 131.311 C 195.363 129.913,194.572 128.123,193.870 125.000 C 193.623 123.900,193.236 122.793,193.010 122.540 C 190.863 120.133,190.147 118.880,188.978 115.481 C 188.100 112.928,187.151 111.003,186.254 109.955 C 185.358 108.908,184.518 107.204,183.847 105.073 C 183.280 103.273,182.497 101.329,182.108 100.753 C 181.719 100.177,180.904 98.997,180.298 98.131 C 179.693 97.265,178.939 95.576,178.624 94.378 C 178.041 92.159,177.125 90.326,175.023 87.168 C 174.375 86.196,173.619 84.539,173.342 83.486 C 172.800 81.429,171.529 79.567,170.131 78.785 C 169.654 78.517,168.697 77.511,168.006 76.549 C 167.316 75.587,166.594 74.800,166.402 74.800 C 166.210 74.800,164.869 73.633,163.421 72.206 C 160.103 68.936,161.107 69.109,146.550 69.301 C 133.437 69.474,128.581 70.162,126.618 72.124 C 126.248 72.495,125.462 72.904,124.872 73.033 C 124.282 73.163,123.088 73.536,122.219 73.863 C 121.349 74.191,119.028 74.638,117.061 74.858 C 113.514 75.254,109.970 76.350,108.782 77.419 C 107.652 78.436,100.146 80.400,97.388 80.400 C 95.775 80.400,93.167 81.360,91.200 82.679 C 90.430 83.195,89.113 83.804,88.274 84.031 C 85.875 84.681,78.799 90.910,74.400 96.243 L 73.400 97.456 73.455 106.028 C 73.526 117.055,74.527 121.238,77.820 124.263 C 78.919 125.273,80.400 127.902,80.400 128.842 C 80.400 129.202,81.075 130.256,81.900 131.186 C 83.563 133.059,85.497 136.346,86.039 138.216 C 86.233 138.886,87.203 140.207,88.196 141.153 C 89.188 142.098,90.000 143.104,90.000 143.388 C 90.000 144.337,92.129 148.594,92.869 149.123 C 93.271 149.410,93.600 149.831,93.600 150.059 C 93.600 150.286,93.932 150.771,94.337 151.136 C 94.743 151.501,95.598 153.004,96.237 154.475 C 96.877 155.947,97.760 157.351,98.200 157.596 C 98.640 157.841,99.900 159.943,101.000 162.267 C 102.207 164.817,103.327 166.644,103.825 166.876 C 104.278 167.087,105.065 168.101,105.573 169.130 C 107.658 173.348,108.097 174.093,110.006 176.647 C 111.103 178.114,112.000 179.725,112.000 180.227 C 112.000 181.048,113.425 183.163,114.678 184.200 C 115.295 184.711,117.396 188.733,117.720 190.022 C 117.855 190.562,118.603 191.633,119.381 192.402 C 120.160 193.171,121.496 195.258,122.351 197.039 C 123.206 198.820,124.167 200.378,124.487 200.501 C 124.807 200.624,125.953 202.496,127.034 204.662 C 128.114 206.828,129.676 209.299,130.505 210.153 C 131.333 211.007,132.124 212.177,132.262 212.753 C 132.618 214.239,134.291 217.048,136.288 219.5
|
|||
|
" href="/">YannStatic</a></div><!--<button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button>--><!-- <li><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></li> -->
|
|||
|
<!-- Champ de recherche -->
|
|||
|
<div id="searchbox" class="search search--dark" style="visibility: visible">
|
|||
|
<div class="main">
|
|||
|
<div class="search__header"></div>
|
|||
|
<div class="search-bar">
|
|||
|
<div class="search-box js-search-box">
|
|||
|
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
|
|||
|
<input id="search-input" type="text" />
|
|||
|
<!-- <div class="search-box__icon-clear js-icon-clear">
|
|||
|
<a><i class="fas fa-times"></i></a>
|
|||
|
</div> -->
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<!-- Script pointing to search-script.js -->
|
|||
|
<script>/*!
|
|||
|
* Simple-Jekyll-Search
|
|||
|
* Copyright 2015-2020, Christian Fei
|
|||
|
* Licensed under the MIT License.
|
|||
|
*/
|
|||
|
|
|||
|
(function(){
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$Templater_7 = {
|
|||
|
compile: compile,
|
|||
|
setOptions: setOptions
|
|||
|
}
|
|||
|
|
|||
|
const options = {}
|
|||
|
options.pattern = /\{(.*?)\}/g
|
|||
|
options.template = ''
|
|||
|
options.middleware = function () {}
|
|||
|
|
|||
|
function setOptions (_options) {
|
|||
|
options.pattern = _options.pattern || options.pattern
|
|||
|
options.template = _options.template || options.template
|
|||
|
if (typeof _options.middleware === 'function') {
|
|||
|
options.middleware = _options.middleware
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function compile (data) {
|
|||
|
return options.template.replace(options.pattern, function (match, prop) {
|
|||
|
const value = options.middleware(prop, data[prop], options.template)
|
|||
|
if (typeof value !== 'undefined') {
|
|||
|
return value
|
|||
|
}
|
|||
|
return data[prop] || match
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
'use strict';
|
|||
|
|
|||
|
function fuzzysearch (needle, haystack) {
|
|||
|
var tlen = haystack.length;
|
|||
|
var qlen = needle.length;
|
|||
|
if (qlen > tlen) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
if (qlen === tlen) {
|
|||
|
return needle === haystack;
|
|||
|
}
|
|||
|
outer: for (var i = 0, j = 0; i < qlen; i++) {
|
|||
|
var nch = needle.charCodeAt(i);
|
|||
|
while (j < tlen) {
|
|||
|
if (haystack.charCodeAt(j++) === nch) {
|
|||
|
continue outer;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
var _$fuzzysearch_1 = fuzzysearch;
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
|
|||
|
|
|||
|
var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
|
|||
|
|
|||
|
function FuzzySearchStrategy () {
|
|||
|
this.matches = function (string, crit) {
|
|||
|
return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
|
|||
|
|
|||
|
function LiteralSearchStrategy () {
|
|||
|
this.matches = function (str, crit) {
|
|||
|
if (!str) return false
|
|||
|
|
|||
|
str = str.trim().toLowerCase()
|
|||
|
crit = crit.trim().toLowerCase()
|
|||
|
|
|||
|
return crit.split(' ').filter(function (word) {
|
|||
|
return str.indexOf(word) >= 0
|
|||
|
}).length === crit.split(' ').length
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$Repository_4 = {
|
|||
|
put: put,
|
|||
|
clear: clear,
|
|||
|
search: search,
|
|||
|
setOptions: __setOptions_4
|
|||
|
}
|
|||
|
|
|||
|
/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
|
|||
|
/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
|
|||
|
|
|||
|
function NoSort () {
|
|||
|
return 0
|
|||
|
}
|
|||
|
|
|||
|
const data = []
|
|||
|
let opt = {}
|
|||
|
|
|||
|
opt.fuzzy = false
|
|||
|
opt.limit = 10
|
|||
|
opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
|
|||
|
opt.sort = NoSort
|
|||
|
opt.exclude = []
|
|||
|
|
|||
|
function put (data) {
|
|||
|
if (isObject(data)) {
|
|||
|
return addObject(data)
|
|||
|
}
|
|||
|
if (isArray(data)) {
|
|||
|
return addArray(data)
|
|||
|
}
|
|||
|
return undefined
|
|||
|
}
|
|||
|
function clear () {
|
|||
|
data.length = 0
|
|||
|
return data
|
|||
|
}
|
|||
|
|
|||
|
function isObject (obj) {
|
|||
|
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
|
|||
|
}
|
|||
|
|
|||
|
function isArray (obj) {
|
|||
|
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
|
|||
|
}
|
|||
|
|
|||
|
function addObject (_data) {
|
|||
|
data.push(_data)
|
|||
|
return data
|
|||
|
}
|
|||
|
|
|||
|
function addArray (_data) {
|
|||
|
const added = []
|
|||
|
clear()
|
|||
|
for (let i = 0, len = _data.length; i < len; i++) {
|
|||
|
if (isObject(_data[i])) {
|
|||
|
added.push(addObject(_data[i]))
|
|||
|
}
|
|||
|
}
|
|||
|
return added
|
|||
|
}
|
|||
|
|
|||
|
function search (crit) {
|
|||
|
if (!crit) {
|
|||
|
return []
|
|||
|
}
|
|||
|
return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
|
|||
|
}
|
|||
|
|
|||
|
function __setOptions_4 (_opt) {
|
|||
|
opt = _opt || {}
|
|||
|
|
|||
|
opt.fuzzy = _opt.fuzzy || false
|
|||
|
opt.limit = _opt.limit || 10
|
|||
|
opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
|
|||
|
opt.sort = _opt.sort || NoSort
|
|||
|
opt.exclude = _opt.exclude || []
|
|||
|
}
|
|||
|
|
|||
|
function findMatches (data, crit, strategy, opt) {
|
|||
|
const matches = []
|
|||
|
for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
|
|||
|
const match = findMatchesInObject(data[i], crit, strategy, opt)
|
|||
|
if (match) {
|
|||
|
matches.push(match)
|
|||
|
}
|
|||
|
}
|
|||
|
return matches
|
|||
|
}
|
|||
|
|
|||
|
function findMatchesInObject (obj, crit, strategy, opt) {
|
|||
|
for (const key in obj) {
|
|||
|
if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
|
|||
|
return obj
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function isExcluded (term, excludedTerms) {
|
|||
|
for (let i = 0, len = excludedTerms.length; i < len; i++) {
|
|||
|
const excludedTerm = excludedTerms[i]
|
|||
|
if (new RegExp(excludedTerm).test(term)) {
|
|||
|
return true
|
|||
|
}
|
|||
|
}
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
/* globals ActiveXObject:false */
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$JSONLoader_2 = {
|
|||
|
load: load
|
|||
|
}
|
|||
|
|
|||
|
function load (location, callback) {
|
|||
|
const xhr = getXHR()
|
|||
|
xhr.open('GET', location, true)
|
|||
|
xhr.onreadystatechange = createStateChangeListener(xhr, callback)
|
|||
|
xhr.send()
|
|||
|
}
|
|||
|
|
|||
|
function createStateChangeListener (xhr, callback) {
|
|||
|
return function () {
|
|||
|
if (xhr.readyState === 4 && xhr.status === 200) {
|
|||
|
try {
|
|||
|
callback(null, JSON.parse(xhr.responseText))
|
|||
|
} catch (err) {
|
|||
|
callback(err, null)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function getXHR () {
|
|||
|
return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$OptionsValidator_3 = function OptionsValidator (params) {
|
|||
|
if (!validateParams(params)) {
|
|||
|
throw new Error('-- OptionsValidator: required options missing')
|
|||
|
}
|
|||
|
|
|||
|
if (!(this instanceof OptionsValidator)) {
|
|||
|
return new OptionsValidator(params)
|
|||
|
}
|
|||
|
|
|||
|
const requiredOptions = params.required
|
|||
|
|
|||
|
this.getRequiredOptions = function () {
|
|||
|
return requiredOptions
|
|||
|
}
|
|||
|
|
|||
|
this.validate = function (parameters) {
|
|||
|
const errors = []
|
|||
|
requiredOptions.forEach(function (requiredOptionName) {
|
|||
|
if (typeof parameters[requiredOptionName] === 'undefined') {
|
|||
|
errors.push(requiredOptionName)
|
|||
|
}
|
|||
|
})
|
|||
|
return errors
|
|||
|
}
|
|||
|
|
|||
|
function validateParams (params) {
|
|||
|
if (!params) {
|
|||
|
return false
|
|||
|
}
|
|||
|
return typeof params.required !== 'undefined' && params.required instanceof Array
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$utils_9 = {
|
|||
|
merge: merge,
|
|||
|
isJSON: isJSON
|
|||
|
}
|
|||
|
|
|||
|
function merge (defaultParams, mergeParams) {
|
|||
|
const mergedOptions = {}
|
|||
|
for (const option in defaultParams) {
|
|||
|
mergedOptions[option] = defaultParams[option]
|
|||
|
if (typeof mergeParams[option] !== 'undefined') {
|
|||
|
mergedOptions[option] = mergeParams[option]
|
|||
|
}
|
|||
|
}
|
|||
|
return mergedOptions
|
|||
|
}
|
|||
|
|
|||
|
function isJSON (json) {
|
|||
|
try {
|
|||
|
if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
|
|||
|
return true
|
|||
|
}
|
|||
|
return false
|
|||
|
} catch (err) {
|
|||
|
return false
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
var _$src_8 = {};
|
|||
|
(function (window) {
|
|||
|
'use strict'
|
|||
|
|
|||
|
let options = {
|
|||
|
searchInput: null,
|
|||
|
resultsContainer: null,
|
|||
|
json: [],
|
|||
|
success: Function.prototype,
|
|||
|
searchResultTemplate: '<li><a href="{url}" title="{desc}">{title}</a></li>',
|
|||
|
templateMiddleware: Function.prototype,
|
|||
|
sortMiddleware: function () {
|
|||
|
return 0
|
|||
|
},
|
|||
|
noResultsText: 'No results found',
|
|||
|
limit: 10,
|
|||
|
fuzzy: false,
|
|||
|
debounceTime: null,
|
|||
|
exclude: []
|
|||
|
}
|
|||
|
|
|||
|
let debounceTimerHandle
|
|||
|
const debounce = function (func, delayMillis) {
|
|||
|
if (delayMillis) {
|
|||
|
clearTimeout(debounceTimerHandle)
|
|||
|
debounceTimerHandle = setTimeout(func, delayMillis)
|
|||
|
} else {
|
|||
|
func.call()
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const requiredOptions = ['searchInput', 'resultsContainer', 'json']
|
|||
|
|
|||
|
/* removed: const _$Templater_7 = require('./Templater') */;
|
|||
|
/* removed: const _$Repository_4 = require('./Repository') */;
|
|||
|
/* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
|
|||
|
const optionsValidator = _$OptionsValidator_3({
|
|||
|
required: requiredOptions
|
|||
|
})
|
|||
|
/* removed: const _$utils_9 = require('./utils') */;
|
|||
|
|
|||
|
window.SimpleJekyllSearch = function (_options) {
|
|||
|
const errors = optionsValidator.validate(_options)
|
|||
|
if (errors.length > 0) {
|
|||
|
throwError('You must specify the following required options: ' + requiredOptions)
|
|||
|
}
|
|||
|
|
|||
|
options = _$utils_9.merge(options, _options)
|
|||
|
|
|||
|
_$Templater_7.setOptions({
|
|||
|
template: options.searchResultTemplate,
|
|||
|
middleware: options.templateMiddleware
|
|||
|
})
|
|||
|
|
|||
|
_$Repository_4.setOptions({
|
|||
|
fuzzy: options.fuzzy,
|
|||
|
limit: options.limit,
|
|||
|
sort: options.sortMiddleware,
|
|||
|
exclude: options.exclude
|
|||
|
})
|
|||
|
|
|||
|
if (_$utils_9.isJSON(options.json)) {
|
|||
|
initWithJSON(options.json)
|
|||
|
} else {
|
|||
|
initWithURL(options.json)
|
|||
|
}
|
|||
|
|
|||
|
const rv = {
|
|||
|
search: search
|
|||
|
}
|
|||
|
|
|||
|
typeof options.success === 'function' && options.success.call(rv)
|
|||
|
return rv
|
|||
|
}
|
|||
|
|
|||
|
function initWithJSON (json) {
|
|||
|
_$Repository_4.put(json)
|
|||
|
registerInput()
|
|||
|
}
|
|||
|
|
|||
|
function initWithURL (url) {
|
|||
|
_$JSONLoader_2.load(url, function (err, json) {
|
|||
|
if (err) {
|
|||
|
throwError('failed to get JSON (' + url + ')')
|
|||
|
}
|
|||
|
initWithJSON(json)
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
function emptyResultsContainer () {
|
|||
|
options.resultsContainer.innerHTML = ''
|
|||
|
}
|
|||
|
|
|||
|
function appendToResultsContainer (text) {
|
|||
|
options.resultsContainer.innerHTML += text
|
|||
|
}
|
|||
|
|
|||
|
function registerInput () {
|
|||
|
options.searchInput.addEventListener('input', function (e) {
|
|||
|
if (isWhitelistedKey(e.which)) {
|
|||
|
emptyResultsContainer()
|
|||
|
debounce(function () { search(e.target.value) }, options.debounceTime)
|
|||
|
}
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
function search (query) {
|
|||
|
if (isValidQuery(query)) {
|
|||
|
emptyResultsContainer()
|
|||
|
render(_$Repository_4.search(query), query)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function render (results, query) {
|
|||
|
const len = results.length
|
|||
|
if (len === 0) {
|
|||
|
return appendToResultsContainer(options.noResultsText)
|
|||
|
}
|
|||
|
for (let i = 0; i < len; i++) {
|
|||
|
results[i].query = query
|
|||
|
appendToResultsContainer(_$Templater_7.compile(results[i]))
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function isValidQuery (query) {
|
|||
|
return query && query.length > 0
|
|||
|
}
|
|||
|
|
|||
|
function isWhitelistedKey (key) {
|
|||
|
return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
|
|||
|
}
|
|||
|
|
|||
|
function throwError (message) {
|
|||
|
throw new Error('SimpleJekyllSearch --- ' + message)
|
|||
|
}
|
|||
|
})(window)
|
|||
|
|
|||
|
}());
|
|||
|
</script>
|
|||
|
|
|||
|
<!-- Configuration -->
|
|||
|
<script>
|
|||
|
SimpleJekyllSearch({
|
|||
|
searchInput: document.getElementById('search-input'),
|
|||
|
resultsContainer: document.getElementById('results-container'),
|
|||
|
json: '/search.json',
|
|||
|
//searchResultTemplate: '<li><a href="https://static.rnmkcy.eu{url}">{date} {title}</a></li>'
|
|||
|
searchResultTemplate: '<li><a href="{url}">{date} {title}</a></li>'
|
|||
|
})
|
|||
|
</script>
|
|||
|
<!-- Fin déclaration champ de recherche --></div><nav class="navigation">
|
|||
|
<ul><li class="navigation__item"><a href="/archive.html">Etiquettes</a></li><li class="navigation__item"><a href="/htmldoc.html">Documents</a></li><li class="navigation__item"><a href="/liens_ttrss.html">Liens</a></li><li class="navigation__item"><a href="/aide-jekyll-text-theme.html">Aide</a></li></ul>
|
|||
|
</nav></div>
|
|||
|
</header>
|
|||
|
|
|||
|
</div><div class="page__content"><div class ="main"><div class="grid grid--reverse">
|
|||
|
<div class="col-main cell cell--auto"><!-- start custom main top snippet --><div id="results-container" class="search-result js-search-result"></div><!-- end custom main top snippet -->
|
|||
|
<article itemscope itemtype="http://schema.org/Article"><div class="article__header"><header><h1 style="color:Tomato;">MULTIBOOT USB 32Go (EFI+GPT et BIOS+GPT/MBR)</h1></header></div><meta itemprop="headline" content="MULTIBOOT USB 32Go (EFI+GPT et BIOS+GPT/MBR)"><div class="article__info clearfix"><ul class="left-col menu"><li>
|
|||
|
<a class="button button--secondary button--pill button--sm"
|
|||
|
href="/archive.html?tag=outils">outils</a>
|
|||
|
</li></ul><ul class="right-col menu"><li>
|
|||
|
<i class="far fa-calendar-alt"></i> <span title="Création" style="color:#FF00FF">10 mars 2020</span>
|
|||
|
|
|||
|
<span title="Modification" style="color:#00FF7F">19 janv. 2023</span></li></ul></div><meta itemprop="datePublished" content="2023-01-19T00:00:00+01:00">
|
|||
|
<meta itemprop="keywords" content="outils"><div class="js-article-content">
|
|||
|
<div class="layout--article"><!-- start custom article top snippet -->
|
|||
|
<style>
|
|||
|
#myBtn {
|
|||
|
display: none;
|
|||
|
position: fixed;
|
|||
|
bottom: 10px;
|
|||
|
right: 10px;
|
|||
|
z-index: 99;
|
|||
|
font-size: 12px;
|
|||
|
font-weight: bold;
|
|||
|
border: none;
|
|||
|
outline: none;
|
|||
|
background-color: white;
|
|||
|
color: black;
|
|||
|
cursor: pointer;
|
|||
|
padding: 5px;
|
|||
|
border-radius: 4px;
|
|||
|
}
|
|||
|
|
|||
|
#myBtn:hover {
|
|||
|
background-color: #555;
|
|||
|
}
|
|||
|
</style>
|
|||
|
|
|||
|
<button onclick="topFunction()" id="myBtn" title="Haut de page">⇧</button>
|
|||
|
|
|||
|
<script>
|
|||
|
//Get the button
|
|||
|
var mybutton = document.getElementById("myBtn");
|
|||
|
|
|||
|
// When the user scrolls down 20px from the top of the document, show the button
|
|||
|
window.onscroll = function() {scrollFunction()};
|
|||
|
|
|||
|
function scrollFunction() {
|
|||
|
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
|
|||
|
mybutton.style.display = "block";
|
|||
|
} else {
|
|||
|
mybutton.style.display = "none";
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// When the user clicks on the button, scroll to the top of the document
|
|||
|
function topFunction() {
|
|||
|
document.body.scrollTop = 0;
|
|||
|
document.documentElement.scrollTop = 0;
|
|||
|
}
|
|||
|
</script>
|
|||
|
|
|||
|
|
|||
|
<!-- end custom article top snippet -->
|
|||
|
<div class="article__content" itemprop="articleBody"><details>
|
|||
|
<summary><b>Afficher/cacher Sommaire</b></summary>
|
|||
|
<!-- affichage sommaire -->
|
|||
|
<div class="toc-aside js-toc-root"></div>
|
|||
|
</details><p><em>Un lecteur USB multiboot permettant de démarrer plusieurs fichiers ISO Archlinux, Debian, Manjaro, PartedMagic, Tails, etc…</em></p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li><a href="#création-usb-multiboot-par-script">Création USB multiboot par script</a>
|
|||
|
<ul>
|
|||
|
<li><a href="#le-script">Le script</a></li>
|
|||
|
<li><a href="#utilisation-du-script">Utilisation du script</a></li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
<li><a href="#création-usb-multiboot-manuelle">Création USB multiboot “manuelle”</a>
|
|||
|
<ul>
|
|||
|
<li><a href="#clé-usb-universelle-bootable-mbr-et-uefi">Clé USB universelle bootable MBR et UEFI</a></li>
|
|||
|
<li><a href="#systèmes-de-fichier-montage-grub">Systèmes de fichier ,montage ,grub</a></li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
<li><a href="#ajout-des-distributions-sur-le-lecteur-usb">Ajout des distributions sur le lecteur USB</a>
|
|||
|
<ul>
|
|||
|
<li><a href="#manjaro">Manjaro</a></li>
|
|||
|
<li><a href="#kali">Kali</a></li>
|
|||
|
<li><a href="#partition-magic">Partition magic</a></li>
|
|||
|
<li><a href="#debian">Debian</a></li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
<li><a href="#démarrez-un-iso-avec-memdisk-facultatif">Démarrez un ISO avec MEMDISK (facultatif)</a></li>
|
|||
|
<li><a href="#test-périphérique-usb-avec-qemu">Test périphérique USB avec QEMU</a></li>
|
|||
|
<li><a href="#annexe">Annexe</a>
|
|||
|
<ul>
|
|||
|
<li><a href="#obtenir-des-fichiers-amorçables-iso">Obtenir des fichiers amorçables ISO</a></li>
|
|||
|
<li><a href="#liens">Liens</a></li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<h2 id="création-usb-multiboot-par-script">Création USB multiboot par script</h2>
|
|||
|
|
|||
|
<h3 id="le-script">Le script</h3>
|
|||
|
|
|||
|
<p><em>Copie du script git https://github.com/aguslr/multibootusb</em></p>
|
|||
|
|
|||
|
<p>Script shell <strong>makeUSB.sh</strong></p>
|
|||
|
|
|||
|
<details>
|
|||
|
<summary>(Afficher/Cacher) <b>makeUSB.sh</b></summary>
|
|||
|
|
|||
|
|
|||
|
<figure class="highlight"><pre><code class="language-shell" data-lang="shell">
|
|||
|
<span class="c">#!/bin/sh</span>
|
|||
|
|
|||
|
<span class="c"># Description : Script pour préparer une clé USB multiboot</span>
|
|||
|
|
|||
|
<span class="c"># Afficher le numéro de ligne lors de l'exécution par bash -x makeUSB.sh</span>
|
|||
|
<span class="o">[</span> <span class="s2">"</span><span class="nv">$BASH</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> <span class="se">\</span>
|
|||
|
<span class="nb">export </span><span class="nv">PS4</span><span class="o">=</span><span class="s1">' +\t $BASH_SOURCE:$LINENO: ${FUNCNAME[0]:+${FUNCNAME[0]}():}'</span>
|
|||
|
|
|||
|
<span class="c"># Exit if there is an unbound variable or an error</span>
|
|||
|
<span class="nb">set</span> <span class="nt">-o</span> nounset
|
|||
|
<span class="nb">set</span> <span class="nt">-o</span> errexit
|
|||
|
|
|||
|
<span class="c"># Valeurs par défaut</span>
|
|||
|
<span class="nv">scriptname</span><span class="o">=</span><span class="si">$(</span><span class="nb">basename</span> <span class="s2">"</span><span class="nv">$0</span><span class="s2">"</span><span class="si">)</span>
|
|||
|
<span class="nv">hybrid</span><span class="o">=</span>0
|
|||
|
<span class="nv">clone</span><span class="o">=</span>0
|
|||
|
<span class="nv">eficonfig</span><span class="o">=</span>0
|
|||
|
<span class="nv">interactive</span><span class="o">=</span>0
|
|||
|
<span class="nv">data_part</span><span class="o">=</span>2
|
|||
|
<span class="nv">data_fmt</span><span class="o">=</span><span class="s2">"vfat"</span>
|
|||
|
<span class="nv">data_size</span><span class="o">=</span><span class="s2">""</span>
|
|||
|
<span class="nv">efi_mnt</span><span class="o">=</span><span class="s2">""</span>
|
|||
|
<span class="nv">data_mnt</span><span class="o">=</span><span class="s2">""</span>
|
|||
|
<span class="nv">data_subdir</span><span class="o">=</span><span class="s2">"boot"</span>
|
|||
|
<span class="nv">repo_dir</span><span class="o">=</span><span class="s2">""</span>
|
|||
|
<span class="nv">tmp_dir</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">TMPDIR</span><span class="p">-/tmp</span><span class="k">}</span><span class="s2">"</span>
|
|||
|
|
|||
|
<span class="c"># Afficher l'utilisation</span>
|
|||
|
<span class="c"># -c, --clone Clone le dépôt Git sur le périphérique</span>
|
|||
|
showUsage<span class="o">()</span> <span class="o">{</span>
|
|||
|
<span class="nb">cat</span> <span class="o"><<-</span> <span class="no">EOF</span><span class="sh">
|
|||
|
Script to prepare multiboot USB drive
|
|||
|
Usage: </span><span class="nv">$scriptname</span><span class="sh"> [options] device [fs-type] [data-size]
|
|||
|
|
|||
|
device Dispositif à modifier (par exemple /dev/sdb)
|
|||
|
fs-type Type de système de fichiers pour la partition de données [ext3|ext4|vfat|ntfs].
|
|||
|
data-size Taille de la partition de données (par exemple, 5G)
|
|||
|
-b, --hybrid Créer un MBR hybride
|
|||
|
-e, --efi Activer la compatibilité EFI
|
|||
|
-i, --interactive Lance gdisk pour créer un MBR hybride
|
|||
|
-h, --help Affiche ce message
|
|||
|
-s, --subdirectory <NAME> Spécifier un sous-répertoire de données (par défaut : "boot")
|
|||
|
Exemple : </span><span class="nv">$scriptname</span><span class="sh"> -b -e /dev/sde
|
|||
|
</span><span class="no"> EOF
|
|||
|
</span><span class="o">}</span>
|
|||
|
|
|||
|
<span class="c"># Nettoyer en quittant</span>
|
|||
|
cleanUp<span class="o">()</span> <span class="o">{</span>
|
|||
|
<span class="c"># Changement de propriétaire des fichiers</span>
|
|||
|
<span class="o">{</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$data_mnt</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> <span class="se">\</span>
|
|||
|
<span class="nb">chown</span> <span class="nt">-R</span> <span class="s2">"</span><span class="nv">$normal_user</span><span class="s2">"</span> <span class="s2">"</span><span class="k">${</span><span class="nv">data_mnt</span><span class="k">}</span><span class="s2">"</span>/<span class="k">*</span> 2>/dev/null<span class="p">;</span> <span class="o">}</span> <span class="se">\</span>
|
|||
|
<span class="o">||</span> <span class="nb">true</span>
|
|||
|
<span class="c"># Démontez tout</span>
|
|||
|
umount <span class="nt">-f</span> <span class="s2">"</span><span class="nv">$efi_mnt</span><span class="s2">"</span> 2>/dev/null <span class="o">||</span> <span class="nb">true
|
|||
|
</span>umount <span class="nt">-f</span> <span class="s2">"</span><span class="nv">$data_mnt</span><span class="s2">"</span> 2>/dev/null <span class="o">||</span> <span class="nb">true</span>
|
|||
|
<span class="c"># Suppression des points de montage</span>
|
|||
|
<span class="o">[</span> <span class="nt">-d</span> <span class="s2">"</span><span class="nv">$efi_mnt</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> <span class="nb">rmdir</span> <span class="s2">"</span><span class="nv">$efi_mnt</span><span class="s2">"</span>
|
|||
|
<span class="o">[</span> <span class="nt">-d</span> <span class="s2">"</span><span class="nv">$data_mnt</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> <span class="nb">rmdir</span> <span class="s2">"</span><span class="nv">$data_mnt</span><span class="s2">"</span>
|
|||
|
<span class="o">[</span> <span class="nt">-d</span> <span class="s2">"</span><span class="nv">$repo_dir</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> <span class="nb">rmdir</span> <span class="s2">"</span><span class="nv">$repo_dir</span><span class="s2">"</span>
|
|||
|
<span class="c"># Exit</span>
|
|||
|
<span class="nb">exit</span> <span class="s2">"</span><span class="k">${</span><span class="nv">1</span><span class="p">-0</span><span class="k">}</span><span class="s2">"</span>
|
|||
|
<span class="o">}</span>
|
|||
|
|
|||
|
<span class="c"># # Vérifiez que le lecteur USB n'est pas monté</span>
|
|||
|
unmountUSB<span class="o">()</span> <span class="o">{</span>
|
|||
|
umount <span class="nt">-f</span> <span class="s2">"</span><span class="k">${</span><span class="nv">1</span><span class="k">}</span><span class="s2">"</span><span class="k">*</span> 2>/dev/null <span class="o">||</span> <span class="nb">true</span>
|
|||
|
<span class="o">}</span>
|
|||
|
|
|||
|
<span class="c"># Trappe les signaux kill (SIGHUP, SIGINT, SIGTERM) pour effectuer un nettoyage et quitter la machine</span>
|
|||
|
<span class="nb">trap</span> <span class="s1">'cleanUp'</span> 1 2 15
|
|||
|
|
|||
|
<span class="c"># Afficher l'aide avant de vérifier la présence de root</span>
|
|||
|
<span class="o">[</span> <span class="s2">"$#"</span> <span class="nt">-eq</span> 0 <span class="o">]</span> <span class="o">&&</span> showUsage <span class="o">&&</span> <span class="nb">exit </span>0
|
|||
|
<span class="k">case</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="k">in</span>
|
|||
|
<span class="nt">-h</span><span class="p">|</span><span class="nt">--help</span><span class="p">)</span>
|
|||
|
showUsage
|
|||
|
<span class="nb">exit </span>0
|
|||
|
<span class="p">;;</span>
|
|||
|
<span class="k">esac</span>
|
|||
|
|
|||
|
<span class="c"># Vérifier la présence de root</span>
|
|||
|
<span class="k">if</span> <span class="o">[</span> <span class="s2">"</span><span class="si">$(</span><span class="nb">id</span> <span class="nt">-u</span><span class="si">)</span><span class="s2">"</span> <span class="nt">-ne</span> 0 <span class="o">]</span><span class="p">;</span> <span class="k">then
|
|||
|
</span><span class="nb">printf</span> <span class="s1">'Ce script doit être exécuté en tant que root. Utilisation de sudo...\n'</span> <span class="s2">"</span><span class="nv">$scriptname</span><span class="s2">"</span> <span class="o">></span>&2
|
|||
|
<span class="nb">exec sudo</span> <span class="nt">-k</span> <span class="nt">--</span> /bin/sh <span class="s2">"</span><span class="nv">$0</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$@</span><span class="s2">"</span> <span class="o">||</span> cleanUp 2
|
|||
|
<span class="k">fi</span>
|
|||
|
|
|||
|
<span class="c"># Récupérer l'utilisateur original</span>
|
|||
|
<span class="nv">normal_user</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">SUDO_USER</span><span class="p">-</span><span class="si">$(</span><span class="nb">who</span> <span class="nt">-m</span> | <span class="nb">awk</span> <span class="s1">'{print $1}'</span><span class="si">)</span><span class="k">}</span><span class="s2">"</span>
|
|||
|
|
|||
|
<span class="c"># Vérifier les arguments</span>
|
|||
|
<span class="k">while</span> <span class="o">[</span> <span class="s2">"$#"</span> <span class="nt">-gt</span> 0 <span class="o">]</span><span class="p">;</span> <span class="k">do
|
|||
|
case</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="k">in</span>
|
|||
|
<span class="nt">-b</span><span class="p">|</span><span class="nt">--hybrid</span><span class="p">)</span>
|
|||
|
<span class="nv">hybrid</span><span class="o">=</span>1
|
|||
|
<span class="p">;;</span>
|
|||
|
<span class="nt">-c</span><span class="p">|</span><span class="nt">--clone</span><span class="p">)</span>
|
|||
|
<span class="nv">clone</span><span class="o">=</span>1
|
|||
|
<span class="p">;;</span>
|
|||
|
<span class="nt">-e</span><span class="p">|</span><span class="nt">--efi</span><span class="p">)</span>
|
|||
|
<span class="nv">eficonfig</span><span class="o">=</span>1
|
|||
|
<span class="nv">data_part</span><span class="o">=</span>3
|
|||
|
<span class="p">;;</span>
|
|||
|
<span class="nt">-i</span><span class="p">|</span><span class="nt">--interactive</span><span class="p">)</span>
|
|||
|
<span class="nv">interactive</span><span class="o">=</span>1
|
|||
|
<span class="p">;;</span>
|
|||
|
<span class="nt">-s</span><span class="p">|</span><span class="nt">--subdirectory</span><span class="p">)</span>
|
|||
|
<span class="nb">shift</span> <span class="o">&&</span> <span class="nv">data_subdir</span><span class="o">=</span><span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span>
|
|||
|
<span class="p">;;</span>
|
|||
|
/dev/<span class="k">*</span><span class="p">)</span>
|
|||
|
<span class="k">if</span> <span class="o">[</span> <span class="nt">-b</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then
|
|||
|
</span><span class="nv">usb_dev</span><span class="o">=</span><span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span>
|
|||
|
<span class="k">else
|
|||
|
</span><span class="nb">printf</span> <span class="s1">'%s: %s périphérique non valide.\n'</span> <span class="s2">"</span><span class="nv">$scriptname</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">></span>&2
|
|||
|
cleanUp 1
|
|||
|
<span class="k">fi</span>
|
|||
|
<span class="p">;;</span>
|
|||
|
<span class="o">[</span>a-z]<span class="k">*</span><span class="p">)</span>
|
|||
|
<span class="nv">data_fmt</span><span class="o">=</span><span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span>
|
|||
|
<span class="p">;;</span>
|
|||
|
<span class="o">[</span>0-9]<span class="k">*</span><span class="p">)</span>
|
|||
|
<span class="nv">data_size</span><span class="o">=</span><span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span>
|
|||
|
<span class="p">;;</span>
|
|||
|
<span class="k">*</span><span class="p">)</span>
|
|||
|
<span class="nb">printf</span> <span class="s1">'%s: %s argument non valide.\n'</span> <span class="s2">"</span><span class="nv">$scriptname</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">></span>&2
|
|||
|
cleanUp 1
|
|||
|
<span class="p">;;</span>
|
|||
|
<span class="k">esac</span>
|
|||
|
<span class="nb">shift
|
|||
|
</span><span class="k">done</span>
|
|||
|
|
|||
|
<span class="c"># Vérifier les arguments requis</span>
|
|||
|
<span class="k">if</span> <span class="o">[</span> <span class="o">!</span> <span class="s2">"</span><span class="nv">$usb_dev</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then
|
|||
|
</span><span class="nb">printf</span> <span class="s1">'%s: Aucun périphérique fourni.\n'</span> <span class="s2">"</span><span class="nv">$scriptname</span><span class="s2">"</span> <span class="o">></span>&2
|
|||
|
showUsage
|
|||
|
cleanUp 1
|
|||
|
<span class="k">fi</span>
|
|||
|
|
|||
|
<span class="c"># Vérifier le binaire d'installation de GRUB</span>
|
|||
|
<span class="nv">grub_cmd</span><span class="o">=</span><span class="si">$(</span><span class="nb">command</span> <span class="nt">-v</span> grub2-install<span class="si">)</span> <span class="se">\</span>
|
|||
|
<span class="o">||</span> <span class="nv">grub_cmd</span><span class="o">=</span><span class="si">$(</span><span class="nb">command</span> <span class="nt">-v</span> grub-install<span class="si">)</span> <span class="se">\</span>
|
|||
|
<span class="o">||</span> cleanUp 3
|
|||
|
|
|||
|
<span class="c"># Démonter le périphérique</span>
|
|||
|
unmountUSB <span class="s2">"</span><span class="nv">$usb_dev</span><span class="s2">"</span>
|
|||
|
|
|||
|
<span class="c"># Confirmez le périphérique</span>
|
|||
|
<span class="nb">printf</span> <span class="s1">'Etes-vous sûr de vouloir utiliser %s? [y/N] '</span> <span class="s2">"</span><span class="nv">$usb_dev</span><span class="s2">"</span>
|
|||
|
<span class="nb">read</span> <span class="nt">-r</span> answer1
|
|||
|
<span class="k">case</span> <span class="s2">"</span><span class="nv">$answer1</span><span class="s2">"</span> <span class="k">in</span>
|
|||
|
<span class="o">[</span>yY][eE][sS]|[yY]<span class="p">)</span>
|
|||
|
<span class="nb">printf</span> <span class="s1">'CELA SUPPRIMERA TOUTES LES DONNÉES. Vous êtes sûr ? [y/N] '</span>
|
|||
|
<span class="nb">read</span> <span class="nt">-r</span> answer2
|
|||
|
<span class="k">case</span> <span class="nv">$answer2</span> <span class="k">in</span>
|
|||
|
<span class="o">[</span>yY][eE][sS]|[yY]<span class="p">)</span>
|
|||
|
<span class="nb">true</span>
|
|||
|
<span class="p">;;</span>
|
|||
|
<span class="k">*</span><span class="p">)</span>
|
|||
|
cleanUp 3
|
|||
|
<span class="p">;;</span>
|
|||
|
<span class="k">esac</span>
|
|||
|
<span class="p">;;</span>
|
|||
|
<span class="k">*</span><span class="p">)</span>
|
|||
|
cleanUp 3
|
|||
|
<span class="p">;;</span>
|
|||
|
<span class="k">esac</span>
|
|||
|
|
|||
|
<span class="c"># Imprimer toutes les étapes</span>
|
|||
|
<span class="nb">set</span> <span class="nt">-o</span> verbose
|
|||
|
|
|||
|
<span class="c"># Suppression des partitions</span>
|
|||
|
sgdisk <span class="nt">--zap-all</span> <span class="s2">"</span><span class="nv">$usb_dev</span><span class="s2">"</span>
|
|||
|
|
|||
|
<span class="c"># Créer une table de partition GUID</span>
|
|||
|
sgdisk <span class="nt">--mbrtogpt</span> <span class="s2">"</span><span class="nv">$usb_dev</span><span class="s2">"</span> <span class="o">||</span> cleanUp 10
|
|||
|
|
|||
|
<span class="c"># Créer une partition de démarrage BIOS (1M)</span>
|
|||
|
sgdisk <span class="nt">--new</span> 1::+1M <span class="nt">--typecode</span> 1:ef02 <span class="se">\</span>
|
|||
|
<span class="nt">--change-name</span> 1:<span class="s2">"BIOS boot partition"</span> <span class="s2">"</span><span class="nv">$usb_dev</span><span class="s2">"</span> <span class="o">||</span> cleanUp 10
|
|||
|
|
|||
|
<span class="c"># Créer une partition système EFI (50M)</span>
|
|||
|
<span class="o">[</span> <span class="s2">"</span><span class="nv">$eficonfig</span><span class="s2">"</span> <span class="nt">-eq</span> 1 <span class="o">]</span> <span class="o">&&</span> <span class="se">\</span>
|
|||
|
<span class="o">{</span> sgdisk <span class="nt">--new</span> 2::+50M <span class="nt">--typecode</span> 2:ef00 <span class="se">\</span>
|
|||
|
<span class="nt">--change-name</span> 2:<span class="s2">"EFI System"</span> <span class="s2">"</span><span class="nv">$usb_dev</span><span class="s2">"</span> <span class="o">||</span> cleanUp 10<span class="p">;</span> <span class="o">}</span>
|
|||
|
|
|||
|
<span class="c"># Définir la taille de la partition de données</span>
|
|||
|
<span class="o">[</span> <span class="nt">-z</span> <span class="s2">"</span><span class="nv">$data_size</span><span class="s2">"</span> <span class="o">]</span> <span class="o">||</span> <span class="se">\</span>
|
|||
|
<span class="nv">data_size</span><span class="o">=</span><span class="s2">"+</span><span class="nv">$data_size</span><span class="s2">"</span>
|
|||
|
|
|||
|
<span class="c"># Définit les informations de la partition de données</span>
|
|||
|
<span class="k">case</span> <span class="s2">"</span><span class="nv">$data_fmt</span><span class="s2">"</span> <span class="k">in
|
|||
|
</span>ext2|ext3|ext4<span class="p">)</span>
|
|||
|
<span class="nv">type_code</span><span class="o">=</span><span class="s2">"8300"</span>
|
|||
|
<span class="nv">part_name</span><span class="o">=</span><span class="s2">"Linux filesystem"</span>
|
|||
|
<span class="p">;;</span>
|
|||
|
msdos|fat|vfat|ntfs<span class="p">)</span>
|
|||
|
<span class="nv">type_code</span><span class="o">=</span><span class="s2">"0700"</span>
|
|||
|
<span class="nv">part_name</span><span class="o">=</span><span class="s2">"Microsoft basic data"</span>
|
|||
|
<span class="p">;;</span>
|
|||
|
<span class="k">*</span><span class="p">)</span>
|
|||
|
<span class="nb">printf</span> <span class="s1">'%s: %s est un type de système de fichiers invalide.\n'</span> <span class="s2">"</span><span class="nv">$scriptname</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$data_fmt</span><span class="s2">"</span> <span class="o">></span>&2
|
|||
|
showUsage
|
|||
|
cleanUp 1
|
|||
|
<span class="p">;;</span>
|
|||
|
<span class="k">esac</span>
|
|||
|
|
|||
|
<span class="c"># Créer une partition de données</span>
|
|||
|
sgdisk <span class="nt">--new</span> <span class="k">${</span><span class="nv">data_part</span><span class="k">}</span>::<span class="s2">"</span><span class="k">${</span><span class="nv">data_size</span><span class="k">}</span><span class="s2">"</span>: <span class="nt">--typecode</span> <span class="k">${</span><span class="nv">data_part</span><span class="k">}</span>:<span class="s2">"</span><span class="nv">$type_code</span><span class="s2">"</span> <span class="se">\</span>
|
|||
|
<span class="nt">--change-name</span> <span class="k">${</span><span class="nv">data_part</span><span class="k">}</span>:<span class="s2">"</span><span class="nv">$part_name</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$usb_dev</span><span class="s2">"</span> <span class="o">||</span> cleanUp 10
|
|||
|
|
|||
|
<span class="c"># Démonter le périphérique</span>
|
|||
|
unmountUSB <span class="s2">"</span><span class="nv">$usb_dev</span><span class="s2">"</span>
|
|||
|
|
|||
|
<span class="c"># Configuration interactive ?</span>
|
|||
|
<span class="k">if</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$interactive</span><span class="s2">"</span> <span class="nt">-eq</span> 1 <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
|
|||
|
<span class="c"># Créer manuellement un MBR hybride</span>
|
|||
|
<span class="c"># https://bit.ly/2z7HBrP</span>
|
|||
|
gdisk <span class="s2">"</span><span class="nv">$usb_dev</span><span class="s2">"</span>
|
|||
|
<span class="k">elif</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$hybrid</span><span class="s2">"</span> <span class="nt">-eq</span> 1 <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
|
|||
|
<span class="c"># Créer un MBR hybride</span>
|
|||
|
<span class="k">if</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$eficonfig</span><span class="s2">"</span> <span class="nt">-eq</span> 1 <span class="o">]</span><span class="p">;</span> <span class="k">then
|
|||
|
</span>sgdisk <span class="nt">--hybrid</span> 1:2:3 <span class="s2">"</span><span class="nv">$usb_dev</span><span class="s2">"</span> <span class="o">||</span> cleanUp 10
|
|||
|
<span class="k">else
|
|||
|
</span>sgdisk <span class="nt">--hybrid</span> 1:2 <span class="s2">"</span><span class="nv">$usb_dev</span><span class="s2">"</span> <span class="o">||</span> cleanUp 10
|
|||
|
<span class="k">fi
|
|||
|
fi</span>
|
|||
|
|
|||
|
<span class="c"># Définir l'indicateur de démarrage pour la partition de données</span>
|
|||
|
sgdisk <span class="nt">--attributes</span> <span class="k">${</span><span class="nv">data_part</span><span class="k">}</span>:set:2 <span class="s2">"</span><span class="nv">$usb_dev</span><span class="s2">"</span> <span class="o">||</span> cleanUp 10
|
|||
|
|
|||
|
<span class="c"># Démonter le périphérique</span>
|
|||
|
unmountUSB <span class="s2">"</span><span class="nv">$usb_dev</span><span class="s2">"</span>
|
|||
|
|
|||
|
<span class="c"># Effacer la partition de démarrage du BIOS</span>
|
|||
|
wipefs <span class="nt">-af</span> <span class="s2">"</span><span class="k">${</span><span class="nv">usb_dev</span><span class="k">}</span><span class="s2">1"</span> <span class="o">||</span> <span class="nb">true</span>
|
|||
|
|
|||
|
<span class="c"># Formatage de la partition système EFI</span>
|
|||
|
<span class="k">if</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$eficonfig</span><span class="s2">"</span> <span class="nt">-eq</span> 1 <span class="o">]</span><span class="p">;</span> <span class="k">then
|
|||
|
</span>wipefs <span class="nt">-af</span> <span class="s2">"</span><span class="k">${</span><span class="nv">usb_dev</span><span class="k">}</span><span class="s2">2"</span> <span class="o">||</span> <span class="nb">true
|
|||
|
</span>mkfs.vfat <span class="nt">-v</span> <span class="nt">-F</span> 32 <span class="s2">"</span><span class="k">${</span><span class="nv">usb_dev</span><span class="k">}</span><span class="s2">2"</span> <span class="o">||</span> cleanUp 10
|
|||
|
<span class="k">fi</span>
|
|||
|
|
|||
|
<span class="c"># Effacer la partition de données</span>
|
|||
|
wipefs <span class="nt">-af</span> <span class="s2">"</span><span class="k">${</span><span class="nv">usb_dev</span><span class="k">}${</span><span class="nv">data_part</span><span class="k">}</span><span class="s2">"</span> <span class="o">||</span> <span class="nb">true</span>
|
|||
|
|
|||
|
<span class="c"># Formatage de la partition de données</span>
|
|||
|
<span class="k">if</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$data_fmt</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"ntfs"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
|
|||
|
<span class="c"># Utiliser le format rapide mkntfs</span>
|
|||
|
mkfs <span class="nt">-t</span> <span class="s2">"</span><span class="nv">$data_fmt</span><span class="s2">"</span> <span class="nt">-f</span> <span class="s2">"</span><span class="k">${</span><span class="nv">usb_dev</span><span class="k">}${</span><span class="nv">data_part</span><span class="k">}</span><span class="s2">"</span> <span class="o">||</span> cleanUp 10
|
|||
|
<span class="k">else
|
|||
|
</span>mkfs <span class="nt">-t</span> <span class="s2">"</span><span class="nv">$data_fmt</span><span class="s2">"</span> <span class="s2">"</span><span class="k">${</span><span class="nv">usb_dev</span><span class="k">}${</span><span class="nv">data_part</span><span class="k">}</span><span class="s2">"</span> <span class="o">||</span> cleanUp 10
|
|||
|
<span class="k">fi</span>
|
|||
|
|
|||
|
<span class="c"># Démonter le périphérique</span>
|
|||
|
unmountUSB <span class="s2">"</span><span class="nv">$usb_dev</span><span class="s2">"</span>
|
|||
|
|
|||
|
<span class="c"># Créer des répertoires temporaires</span>
|
|||
|
<span class="nv">efi_mnt</span><span class="o">=</span><span class="si">$(</span><span class="nb">mktemp</span> <span class="nt">-p</span> <span class="s2">"</span><span class="nv">$tmp_dir</span><span class="s2">"</span> <span class="nt">-d</span> efi.XXXX<span class="si">)</span> <span class="o">||</span> cleanUp 10
|
|||
|
<span class="nv">data_mnt</span><span class="o">=</span><span class="si">$(</span><span class="nb">mktemp</span> <span class="nt">-p</span> <span class="s2">"</span><span class="nv">$tmp_dir</span><span class="s2">"</span> <span class="nt">-d</span> data.XXXX<span class="si">)</span> <span class="o">||</span> cleanUp 10
|
|||
|
<span class="nv">repo_dir</span><span class="o">=</span><span class="si">$(</span><span class="nb">mktemp</span> <span class="nt">-p</span> <span class="s2">"</span><span class="nv">$tmp_dir</span><span class="s2">"</span> <span class="nt">-d</span> repo.XXXX<span class="si">)</span> <span class="o">||</span> cleanUp 10
|
|||
|
|
|||
|
<span class="c"># Monter la partition système EFI</span>
|
|||
|
<span class="o">[</span> <span class="s2">"</span><span class="nv">$eficonfig</span><span class="s2">"</span> <span class="nt">-eq</span> 1 <span class="o">]</span> <span class="o">&&</span> <span class="se">\</span>
|
|||
|
<span class="o">{</span> mount <span class="s2">"</span><span class="k">${</span><span class="nv">usb_dev</span><span class="k">}</span><span class="s2">2"</span> <span class="s2">"</span><span class="nv">$efi_mnt</span><span class="s2">"</span> <span class="o">||</span> cleanUp 10<span class="p">;</span> <span class="o">}</span>
|
|||
|
|
|||
|
<span class="c"># Monter la partition de données</span>
|
|||
|
mount <span class="s2">"</span><span class="k">${</span><span class="nv">usb_dev</span><span class="k">}${</span><span class="nv">data_part</span><span class="k">}</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$data_mnt</span><span class="s2">"</span> <span class="o">||</span> cleanUp 10
|
|||
|
|
|||
|
<span class="c"># Installer GRUB pour EFI</span>
|
|||
|
<span class="o">[</span> <span class="s2">"</span><span class="nv">$eficonfig</span><span class="s2">"</span> <span class="nt">-eq</span> 1 <span class="o">]</span> <span class="o">&&</span> <span class="se">\</span>
|
|||
|
<span class="o">{</span> <span class="nv">$grub_cmd</span> <span class="nt">--target</span><span class="o">=</span>x86_64-efi <span class="nt">--efi-directory</span><span class="o">=</span><span class="s2">"</span><span class="nv">$efi_mnt</span><span class="s2">"</span> <span class="se">\</span>
|
|||
|
<span class="nt">--boot-directory</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">data_mnt</span><span class="k">}</span><span class="s2">/</span><span class="k">${</span><span class="nv">data_subdir</span><span class="k">}</span><span class="s2">"</span> <span class="nt">--removable</span> <span class="nt">--recheck</span> <span class="se">\</span>
|
|||
|
<span class="o">||</span> cleanUp 10<span class="p">;</span> <span class="o">}</span>
|
|||
|
|
|||
|
<span class="c"># Installer GRUB pour BIOS</span>
|
|||
|
<span class="nv">$grub_cmd</span> <span class="nt">--force</span> <span class="nt">--target</span><span class="o">=</span>i386-pc <span class="se">\</span>
|
|||
|
<span class="nt">--boot-directory</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">data_mnt</span><span class="k">}</span><span class="s2">/</span><span class="k">${</span><span class="nv">data_subdir</span><span class="k">}</span><span class="s2">"</span> <span class="nt">--recheck</span> <span class="s2">"</span><span class="nv">$usb_dev</span><span class="s2">"</span> <span class="se">\</span>
|
|||
|
<span class="o">||</span> cleanUp 10
|
|||
|
|
|||
|
<span class="c"># Installer GRUB de secours</span>
|
|||
|
<span class="nv">$grub_cmd</span> <span class="nt">--force</span> <span class="nt">--target</span><span class="o">=</span>i386-pc <span class="se">\</span>
|
|||
|
<span class="nt">--boot-directory</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">data_mnt</span><span class="k">}</span><span class="s2">/</span><span class="k">${</span><span class="nv">data_subdir</span><span class="k">}</span><span class="s2">"</span> <span class="nt">--recheck</span> <span class="s2">"</span><span class="k">${</span><span class="nv">usb_dev</span><span class="k">}${</span><span class="nv">data_part</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span>
|
|||
|
<span class="o">||</span> <span class="nb">true</span>
|
|||
|
|
|||
|
<span class="c"># Créer les répertoires nécessaires</span>
|
|||
|
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">data_mnt</span><span class="k">}</span><span class="s2">/</span><span class="k">${</span><span class="nv">data_subdir</span><span class="k">}</span><span class="s2">/isos"</span> <span class="o">||</span> cleanUp 10
|
|||
|
|
|||
|
<span class="c">#if [ "$clone" -eq 1 ]; then</span>
|
|||
|
<span class="c"># Cloner le dépôt Git</span>
|
|||
|
<span class="c"># (cd "$repo_dir" && \</span>
|
|||
|
<span class="c"># git clone https://github.com/aguslr/multibootusb . && \</span>
|
|||
|
<span class="c"># # Déplacer tous les fichiers et dossiers visibles et cachés, sauf '.' et '...'.</span>
|
|||
|
<span class="c"># for x in * .[!.]* ..?*; do if [ -e "$x" ]; then mv -- "$x" \</span>
|
|||
|
<span class="c"># "${data_mnt}/${data_subdir}"/grub*/; fi; done) \</span>
|
|||
|
<span class="c"># || cleanUp 10</span>
|
|||
|
<span class="c">#else</span>
|
|||
|
<span class="c"># Copier les fichiers</span>
|
|||
|
<span class="nb">cp</span> <span class="nt">-R</span> ./boot/grub/mbusb.<span class="k">*</span> <span class="s2">"</span><span class="k">${</span><span class="nv">data_mnt</span><span class="k">}</span><span class="s2">/</span><span class="k">${</span><span class="nv">data_subdir</span><span class="k">}</span><span class="s2">"</span>/grub<span class="k">*</span>/ <span class="se">\</span>
|
|||
|
<span class="o">||</span> cleanUp 10
|
|||
|
<span class="c"># Copier la configuration GRUB</span>
|
|||
|
<span class="nb">cp</span> ./boot/grub/grub.cfg <span class="s2">"</span><span class="k">${</span><span class="nv">data_mnt</span><span class="k">}</span><span class="s2">/</span><span class="k">${</span><span class="nv">data_subdir</span><span class="k">}</span><span class="s2">"</span>/grub<span class="k">*</span>/ <span class="se">\</span>
|
|||
|
<span class="o">||</span> cleanUp 10
|
|||
|
<span class="c"># Copier les thèmes GRUB</span>
|
|||
|
<span class="nb">cp</span> <span class="nt">-R</span> ./boot/grub/themes/<span class="k">*</span> <span class="s2">"</span><span class="k">${</span><span class="nv">data_mnt</span><span class="k">}</span><span class="s2">/</span><span class="k">${</span><span class="nv">data_subdir</span><span class="k">}</span><span class="s2">"</span>/grub/themes/ <span class="se">\</span>
|
|||
|
<span class="o">||</span> cleanUp 10
|
|||
|
<span class="c">#fi</span>
|
|||
|
|
|||
|
<span class="c"># Renommer la configuration d'exemple</span>
|
|||
|
<span class="c">#( cd "${data_mnt}/${data_subdir}"/grub*/ && cp grub.cfg.example grub.cfg ) \</span>
|
|||
|
<span class="c"># || cleanUp 10</span>
|
|||
|
|
|||
|
<span class="c"># Télécharger memdisk</span>
|
|||
|
<span class="nv">syslinux_url</span><span class="o">=</span><span class="s1">'https://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-6.03.tar.gz'</span>
|
|||
|
<span class="o">{</span> wget <span class="nt">-qO</span> - <span class="s2">"</span><span class="nv">$syslinux_url</span><span class="s2">"</span> 2>/dev/null <span class="o">||</span> curl <span class="nt">-sL</span> <span class="s2">"</span><span class="nv">$syslinux_url</span><span class="s2">"</span> 2>/dev/null<span class="p">;</span> <span class="o">}</span> <span class="se">\</span>
|
|||
|
| <span class="nb">tar</span> <span class="nt">-xz</span> <span class="nt">-C</span> <span class="s2">"</span><span class="k">${</span><span class="nv">data_mnt</span><span class="k">}</span><span class="s2">/</span><span class="k">${</span><span class="nv">data_subdir</span><span class="k">}</span><span class="s2">"</span>/grub<span class="k">*</span>/ <span class="nt">--no-same-owner</span> <span class="nt">--strip-components</span> 3 <span class="se">\</span>
|
|||
|
<span class="s1">'syslinux-6.03/bios/memdisk/memdisk'</span> <span class="se">\</span>
|
|||
|
<span class="o">||</span> cleanUp 10
|
|||
|
|
|||
|
<span class="c"># Nettoyer et quitter</span>
|
|||
|
cleanUp
|
|||
|
<span class="nb">exit </span>0</code></pre></figure>
|
|||
|
|
|||
|
|
|||
|
</details>
|
|||
|
|
|||
|
<p>Le rendre exécutable</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chmo +x makeUSB.sh
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="utilisation-du-script">Utilisation du script</h3>
|
|||
|
|
|||
|
<p>Il suffit de l’exécuter en tant que root:</p>
|
|||
|
|
|||
|
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./makeUSB.sh <span class="nt">-b</span> <span class="nt">-e</span> <device>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>-b</strong> pour créer un hybride MBR et <strong>-e</strong> pour la compatibilité UEFI<br />
|
|||
|
Où <code class="language-plaintext highlighter-rouge"><device></code> est le nom du périphérique USB (par exemple <em>/dev/sd</em>). <br />
|
|||
|
Exécutez <code class="language-plaintext highlighter-rouge">mount</code> pour obtenir cette information.
|
|||
|
Autre possibilité , juste après avoir inséré la clé USB , exécuter <code class="language-plaintext highlighter-rouge">dmesg</code> dans une fenêtre terminal :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[ 2541.013465] sd 4:0:0:0: [sde] Attached SCSI removable disk
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Dans notre exemple la clé est sous <strong>/dev/sdd</strong></p>
|
|||
|
|
|||
|
<p>** AVERTISSEMENT **: Cela efface toutes les données du périphérique, alors assurez-vous de choisir le bon.</p>
|
|||
|
|
|||
|
<h2 id="création-usb-multiboot-manuelle">Création USB multiboot “manuelle”</h2>
|
|||
|
|
|||
|
<h3 id="clé-usb-universelle-bootable-mbr-et-uefi">Clé USB universelle bootable MBR et UEFI</h3>
|
|||
|
|
|||
|
<p><a href="https://wiki.archlinux.org/index.php/Multiboot_USB_drive#Hybrid_UEFI_GPT_.2B_BIOS_GPT.2FMBR_boot">Hybrid UEFI GPT + BIOS GPT/MBR boot(archlinux wiki)</a></p>
|
|||
|
|
|||
|
<p>Cette configuration est utile pour créer une clé USB universelle, bootable partout. Tout d’abord, vous devez créer une table de partitions GPT sur votre périphérique. Vous avez besoin d’au moins 3 partitions:</p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li>Une partition d’amorçage BIOS (type EF02) qui doit doit avoir une taille de 1 Mo</li>
|
|||
|
<li>Une partition système EFI (type EF00 avec un système de fichiers FAT32) au minimum 50 Mo</li>
|
|||
|
<li>Votre partition de données (utilisez un système de fichiers pris en charge par GRUB) peut prendre le reste de l’espace de votre lecteur</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<p>Ensuite, vous devez créer une table de partition hybride MBR, car définir l’indicateur de démarrage sur la partition de protection MBR peut ne pas être suffisant.</p>
|
|||
|
|
|||
|
<p>Mode su</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Identifier la clé USB par dmesg (exemple /dev/sdd</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dmesg
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> [25430.573773] sd 4:0:0:0: [sdd] Attached SCSI removable disk
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>La clé est sur /dev/sdd</p>
|
|||
|
|
|||
|
<p>On va initialiser la clé USB</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gdisk /dev/sdd
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>GPT fdisk (gdisk) version 1.0.4
|
|||
|
|
|||
|
Partition table scan:
|
|||
|
MBR: protective
|
|||
|
BSD: not present
|
|||
|
APM: not present
|
|||
|
GPT: present
|
|||
|
|
|||
|
Found valid GPT with protective MBR; using GPT.
|
|||
|
|
|||
|
Command (? for help): x
|
|||
|
|
|||
|
Expert command (? for help): z
|
|||
|
About to wipe out GPT on /dev/sdd. Proceed? (Y/N): Y
|
|||
|
GPT data structures destroyed! You may now partition the disk using fdisk or
|
|||
|
other utilities.
|
|||
|
Blank out MBR? (Y/N): Y
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Lancer gdisk pour préparer la clé USB</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gdisk /dev/sdd
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>GPT fdisk (gdisk) version 1.0.1
|
|||
|
|
|||
|
Partition table scan:
|
|||
|
MBR: not present
|
|||
|
BSD: not present
|
|||
|
APM: not present
|
|||
|
GPT: not present
|
|||
|
|
|||
|
Creating new GPT entries.
|
|||
|
|
|||
|
Command (? for help): o
|
|||
|
This option deletes all partitions and creates a new protective MBR.
|
|||
|
Proceed? (Y/N): Y
|
|||
|
|
|||
|
Command (? for help): n
|
|||
|
Partition number (1-128, default 1):
|
|||
|
First sector (34-30282974, default = 2048) or {+-}size{KMGTP}:
|
|||
|
Last sector (2048-30282974, default = 30282974) or {+-}size{KMGTP}: +1M
|
|||
|
Current type is 'Linux filesystem'
|
|||
|
Hex code or GUID (L to show codes, Enter = 8300): EF02
|
|||
|
Changed type of partition to 'BIOS boot partition'
|
|||
|
|
|||
|
Command (? for help): n
|
|||
|
Partition number (2-128, default 2):
|
|||
|
First sector (34-30282974, default = 4096) or {+-}size{KMGTP}:
|
|||
|
Last sector (4096-30282974, default = 30282974) or {+-}size{KMGTP}: +50M
|
|||
|
Current type is 'Linux filesystem'
|
|||
|
Hex code or GUID (L to show codes, Enter = 8300): EF00
|
|||
|
Changed type of partition to 'EFI System'
|
|||
|
|
|||
|
Command (? for help): n
|
|||
|
Partition number (3-128, default 3):
|
|||
|
First sector (34-30282974, default = 106496) or {+-}size{KMGTP}:
|
|||
|
Last sector (106496-30282974, default = 30282974) or {+-}size{KMGTP}:
|
|||
|
Current type is 'Linux filesystem'
|
|||
|
Hex code or GUID (L to show codes, Enter = 8300): 0700
|
|||
|
Changed type of partition to 'Microsoft basic data'
|
|||
|
|
|||
|
Command (? for help): r
|
|||
|
|
|||
|
Recovery/transformation command (? for help): h # h --> make hybrid MBR
|
|||
|
|
|||
|
WARNING! Hybrid MBRs are flaky and dangerous! If you decide not to use one,
|
|||
|
just hit the Enter key at the below prompt and your MBR partition table will
|
|||
|
be untouched.
|
|||
|
|
|||
|
Type from one to three GPT partition numbers, separated by spaces, to be
|
|||
|
added to the hybrid MBR, in sequence: 1 2 3
|
|||
|
Place EFI GPT (0xEE) partition first in MBR (good for GRUB)? (Y/N): N
|
|||
|
|
|||
|
Creating entry for GPT partition #1 (MBR partition #1)
|
|||
|
Enter an MBR hex code (default EF):
|
|||
|
Set the bootable flag? (Y/N): N
|
|||
|
|
|||
|
Creating entry for GPT partition #2 (MBR partition #2)
|
|||
|
Enter an MBR hex code (default EF):
|
|||
|
Set the bootable flag? (Y/N): N
|
|||
|
|
|||
|
Creating entry for GPT partition #3 (MBR partition #3)
|
|||
|
Enter an MBR hex code (default 07):
|
|||
|
Set the bootable flag? (Y/N): Y
|
|||
|
|
|||
|
Recovery/transformation command (? for help): x # x --> extra functionality (experts only)
|
|||
|
|
|||
|
Expert command (? for help): h # h --> recompute CHS values in protective/hybrid MBR
|
|||
|
|
|||
|
Expert command (? for help): w
|
|||
|
|
|||
|
Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
|
|||
|
PARTITIONS!!
|
|||
|
|
|||
|
Do you want to proceed? (Y/N): Y
|
|||
|
OK; writing new GUID partition table (GPT) to /dev/sdd.
|
|||
|
The operation has completed successfully.
|
|||
|
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Structure de la clé USB</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
|
|||
|
sdd 8:48 1 29,3G 0 disk
|
|||
|
├─sdd1 8:49 1 1M 0 part
|
|||
|
├─sdd2 8:50 1 50M 0 part
|
|||
|
└─sdd3 8:51 1 29,2G 0 part
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="systèmes-de-fichier-montage-grub">Systèmes de fichier ,montage ,grub</h3>
|
|||
|
|
|||
|
<p><strong>Systèmes de fichier</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pacman -S dosfstools # pour les systèmes de fichier vfat
|
|||
|
mkfs.vfat -F 32 /dev/sdd2 # FAT32 pour EFI
|
|||
|
mkfs.vfat -F 32 /dev/sdd3 # FAT32 partition principale
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Tout d’abord, vous devez monter la partition EFI System (Ex: /mnt/multiboot/efi) et la partition de données (Ex: /mnt/multiboot/data) de votre clé USB (EX: /dev/sdd).</p>
|
|||
|
|
|||
|
<p><strong>montage</strong></p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> <span class="nt">-p</span> /mnt/multiboot/efi
|
|||
|
mount /dev/sdd3 /mnt/multiboot
|
|||
|
mount /dev/sdd2 /mnt/multiboot/efi
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>grub</strong><br />
|
|||
|
Vous pouvez maintenant installer GRUB pour prendre en charge EFI + GPT et BIOS + GPT/MBR. La configuration GRUB (–boot-directory) peut être conservée au même endroit.</p>
|
|||
|
|
|||
|
<p>Installation GRUB pour EFI</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>grub-install --target=x86_64-efi --efi-directory=/mnt/multiboot/efi --boot-directory=/mnt/multiboot/boot --removable --recheck /dev/sdd
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Installation GRUB pour BIOS</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>grub-install --target=i386-pc --boot-directory=/mnt/multiboot/boot --recheck /dev/sdd
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>La partition de données est montée sur <strong>/mnt/multiboot</strong> et le dossier multiboot <strong>iso/multibootusb/</strong> <br />
|
|||
|
Copiez les fichiers GRUB nécessaires:</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># répertoire nommé *isos* pour les fichiers ISO
|
|||
|
mkdir -p /mnt/multiboot/boot/isos
|
|||
|
#mkdir -p /mnt/multiboot/boot/grub/grub.d
|
|||
|
# Copie des fichiers GRUB
|
|||
|
cp -rf iso/multibootusb/boot/grub/mbusb.d /mnt/multiboot/boot/grub/
|
|||
|
cp iso/multibootusb/boot/grub/grub.cfg /mnt/multiboot/boot/grub/
|
|||
|
# Le fichier commun à toutes les distributions
|
|||
|
cp iso/multibootusb/boot/grub/mbusb.cfg /mnt/multiboot/boot/grub/
|
|||
|
# les thèmes
|
|||
|
cp -rf iso/multibootusb/boot/grub/themes /mnt/multiboot/boot/grub/
|
|||
|
# splash.png
|
|||
|
cp iso/multibootusb/boot/grub/splash.png /mnt/multiboot/boot/grub/
|
|||
|
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Le fichier <strong>/mnt/multiboot/boot/grub/grub.cfg</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Config for GNU GRand Unified Bootloader (GRUB)
|
|||
|
|
|||
|
insmod font
|
|||
|
if loadfont unicode ; then
|
|||
|
if keystatus --shift ; then true ; else
|
|||
|
if [ x"${grub_platform}" = xefi ]; then
|
|||
|
insmod efi_gop
|
|||
|
insmod efi_uga
|
|||
|
insmod videotest
|
|||
|
insmod videoinfo
|
|||
|
else
|
|||
|
insmod vbe
|
|||
|
insmod vga
|
|||
|
fi
|
|||
|
insmod gfxterm
|
|||
|
insmod gfxmenu
|
|||
|
set gfxmode=auto
|
|||
|
set gfxpayload=auto
|
|||
|
terminal_output gfxterm
|
|||
|
if terminal_output gfxterm ; then true ; else
|
|||
|
terminal gfxterm
|
|||
|
fi
|
|||
|
fi
|
|||
|
fi
|
|||
|
|
|||
|
# Timeout for menu
|
|||
|
# set timeout=30
|
|||
|
|
|||
|
insmod png
|
|||
|
set theme=${prefix}/themes/Virtualfuture/theme.txt
|
|||
|
|
|||
|
# Load MBUSB configuration
|
|||
|
# Partition holding files
|
|||
|
probe -u $root --set=rootuuid
|
|||
|
set imgdevpath="/dev/disk/by-uuid/$rootuuid"
|
|||
|
export imgdevpath rootuuid
|
|||
|
|
|||
|
# Custom variables
|
|||
|
set isopath="/boot/isos"
|
|||
|
export isopath
|
|||
|
export theme
|
|||
|
|
|||
|
# Load modules
|
|||
|
insmod regexp
|
|||
|
insmod all_video
|
|||
|
|
|||
|
# MultiBoot USB menu
|
|||
|
# Warning for 32-bit systems
|
|||
|
if ! cpuid -l; then
|
|||
|
clear
|
|||
|
echo "This is a 32-bit computer."
|
|||
|
echo "You won't get to use 64-bit software on it."
|
|||
|
echo
|
|||
|
echo -n "To continue, press ESC or wait 10 seconds... "
|
|||
|
sleep --interruptible 10
|
|||
|
echo
|
|||
|
echo
|
|||
|
fi
|
|||
|
|
|||
|
# Load custom configuration
|
|||
|
if [ -e "$prefix/mbusb.cfg.local" ]; then
|
|||
|
source "$prefix/mbusb.cfg.local"
|
|||
|
fi
|
|||
|
|
|||
|
# Load configuration files
|
|||
|
echo -n "Loading configuration files... "
|
|||
|
for cfgfile in $prefix/mbusb.d/*.d/*.cfg; do
|
|||
|
source "$cfgfile"
|
|||
|
done
|
|||
|
|
|||
|
# Grub options
|
|||
|
submenu "GRUB2 options ->" {
|
|||
|
menuentry "List devices/partitions" {
|
|||
|
ls -l
|
|||
|
sleep --interruptible 9999
|
|||
|
}
|
|||
|
|
|||
|
menuentry "Enable GRUB2's LVM support" {
|
|||
|
insmod lvm
|
|||
|
}
|
|||
|
|
|||
|
menuentry "Enable GRUB2's RAID support" {
|
|||
|
insmod dm_nv
|
|||
|
insmod mdraid09_be
|
|||
|
insmod mdraid09
|
|||
|
insmod mdraid1x
|
|||
|
insmod raid5rec
|
|||
|
insmod raid6rec
|
|||
|
}
|
|||
|
|
|||
|
menuentry "Enable GRUB2's PATA support (to work around BIOS bugs/limitations)" {
|
|||
|
insmod ata
|
|||
|
update_paths
|
|||
|
}
|
|||
|
|
|||
|
menuentry "Enable GRUB2's USB support *experimental*" {
|
|||
|
insmod ohci
|
|||
|
insmod uhci
|
|||
|
insmod usbms
|
|||
|
update_paths
|
|||
|
}
|
|||
|
|
|||
|
menuentry "Mount encrypted volumes (LUKS and geli)" {
|
|||
|
insmod luks
|
|||
|
insmod geli
|
|||
|
cryptomount -a
|
|||
|
}
|
|||
|
|
|||
|
menuentry "Enable serial terminal" {
|
|||
|
serial
|
|||
|
terminal_input --append serial
|
|||
|
terminal_output --append serial
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
# Reboot
|
|||
|
menuentry "Reboot" {
|
|||
|
reboot
|
|||
|
}
|
|||
|
# Poweroff
|
|||
|
menuentry "Poweroff" {
|
|||
|
halt
|
|||
|
}
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h2 id="ajout-des-distributions-sur-le-lecteur-usb">Ajout des distributions sur le lecteur USB</h2>
|
|||
|
|
|||
|
<p>Le fichier commun tous les OS <strong>mbusb.cfg</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/mnt/multiboot/boot/grub/mbusb.cfg
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Partition holding files
|
|||
|
probe -u $root --set=rootuuid
|
|||
|
set imgdevpath="/dev/disk/by-uuid/$rootuuid"
|
|||
|
export imgdevpath rootuuid
|
|||
|
|
|||
|
# Custom variables
|
|||
|
set isopath="/boot/isos"
|
|||
|
export isopath
|
|||
|
|
|||
|
# Load modules
|
|||
|
insmod regexp
|
|||
|
insmod all_video
|
|||
|
|
|||
|
# MultiBoot USB menu
|
|||
|
submenu "Multiboot ->" {
|
|||
|
# Warning for 32-bit systems
|
|||
|
if ! cpuid -l; then
|
|||
|
clear
|
|||
|
echo "This is a 32-bit computer."
|
|||
|
echo "You won't get to use 64-bit software on it."
|
|||
|
echo
|
|||
|
echo -n "To continue, press ESC or wait 10 seconds... "
|
|||
|
sleep --interruptible 10
|
|||
|
echo
|
|||
|
echo
|
|||
|
fi
|
|||
|
|
|||
|
# Load custom configuration
|
|||
|
if [ -e "$prefix/mbusb.cfg.local" ]; then
|
|||
|
source "$prefix/mbusb.cfg.local"
|
|||
|
fi
|
|||
|
|
|||
|
# Load configuration files
|
|||
|
echo -n "Loading configuration files... "
|
|||
|
for cfgfile in $prefix/mbusb.d/*.d/*.cfg; do
|
|||
|
source "$cfgfile"
|
|||
|
done
|
|||
|
}
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="manjaro">Manjaro</h3>
|
|||
|
|
|||
|
<p>Créer le dossier</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir -p /mnt/multiboot/boot/grub/mbusb.d/manjaro.d/
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Créer le fichier de configuration</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /mnt/multiboot/boot/grub/mbusb.d/manjaro.d/generic.cfg
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>for isofile in $isopath/manjaro-*.iso; do
|
|||
|
if [ -e "$isofile" ]; then
|
|||
|
regexp --set=isoname "$isopath/(.*)" "$isofile"
|
|||
|
submenu "$isoname ->" "$isofile" {
|
|||
|
iso_path="$2"
|
|||
|
loopback loop "$iso_path"
|
|||
|
probe --label --set=cd_label (loop)
|
|||
|
menuentry "Start Manjaro Linux" {
|
|||
|
bootoptions="img_dev=$imgdevpath img_loop=$iso_path earlymodules=loop misobasedir=manjaro misolabel=$cd_label nouveau.modeset=1 i915.modeset=1 radeon.modeset=1 logo.nologo overlay=free lang=fr_FR keytable=fr quiet splash showopts"
|
|||
|
linux (loop)/boot/vmlinuz-* $bootoptions
|
|||
|
initrd (loop)/boot/initramfs-*.img
|
|||
|
}
|
|||
|
menuentry "Start (non-free drivers)" {
|
|||
|
bootoptions="img_dev=$imgdevpath img_loop=$iso_path earlymodules=loop misobasedir=manjaro misolabel=$cd_label nouveau.modeset=0 i915.modeset=1 radeon.modeset=0 nonfree=yes logo.nologo overlay=nonfree lang=fr_FR keytable=fr quiet splash showopts"
|
|||
|
linux (loop)/boot/vmlinuz-* $bootoptions
|
|||
|
initrd (loop)/boot/initramfs-*.img
|
|||
|
}
|
|||
|
}
|
|||
|
fi
|
|||
|
done
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Copier le fichier iso manjaro dans le dossier <code class="language-plaintext highlighter-rouge">/mnt/multiboot/boot/isos/</code></p>
|
|||
|
|
|||
|
<h3 id="kali">Kali</h3>
|
|||
|
|
|||
|
<p>Créer le dossier</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir -p /mnt/multiboot/boot/grub/mbusb.d/kali.d/
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Créer le fichier de configuration</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /mnt/multiboot/boot/grub/mbusb.d/kali.d/generic.cfg
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>for isofile in $isopath/kali-linux-*.iso; do
|
|||
|
if [ -e "$isofile" ]; then
|
|||
|
regexp --set=isoname "$isopath/(.*)" "$isofile"
|
|||
|
submenu "$isoname ->" "$isofile" {
|
|||
|
iso_path="$2"
|
|||
|
loopback loop "$iso_path"
|
|||
|
# Live boot
|
|||
|
menuentry "Live system (amd64)" --hotkey=l {
|
|||
|
linux (loop)/live/vmlinuz-5.18.0-kali5-amd64 boot=live components quiet splash noeject findiso=${iso_path}
|
|||
|
initrd (loop)/live/initrd.img-5.18.0-kali5-amd64
|
|||
|
}
|
|||
|
if [ "${grub_platform}" = "efi" ]; then
|
|||
|
menuentry "Live system (amd64 fail-safe mode)" {
|
|||
|
linux (loop)/live/vmlinuz-5.18.0-kali5-amd64 boot=live components noeject memtest noapic noapm nodma nomce nolapic nosmp nosplash vga=normal
|
|||
|
initrd (loop)/live/initrd.img-5.18.0-kali5-amd64
|
|||
|
}
|
|||
|
else
|
|||
|
menuentry "Live system (amd64 fail-safe mode)" {
|
|||
|
linux (loop)/live/vmlinuz-5.18.0-kali5-amd64 boot=live components noeject memtest noapic noapm nodma nomce nolapic nomodeset nosmp nosplash vga=normal
|
|||
|
initrd (loop)/live/initrd.img-5.18.0-kali5-amd64
|
|||
|
}
|
|||
|
fi
|
|||
|
|
|||
|
menuentry "Live system (amd64 forensic mode)" {
|
|||
|
linux (loop)/live/vmlinuz-5.18.0-kali5-amd64 boot=live components quiet splash noeject findiso=${iso_path} noswap noautomount
|
|||
|
initrd (loop)/live/initrd.img-5.18.0-kali5-amd64
|
|||
|
}
|
|||
|
menuentry "Live system with USB persistence (check kali.org/prst)" {
|
|||
|
linux (loop)/live/vmlinuz-5.18.0-kali5-amd64 boot=live components quiet splash noeject findiso=${iso_path} persistence
|
|||
|
initrd (loop)/live/initrd.img-5.18.0-kali5-amd64
|
|||
|
}
|
|||
|
menuentry "Live system with USB Encrypted persistence" {
|
|||
|
linux (loop)/live/vmlinuz-5.18.0-kali5-amd64 boot=live components quiet splash noeject findiso=${iso_path} persistent=cryptsetup persistence-encryption=luks persistence
|
|||
|
initrd (loop)/live/initrd.img-5.18.0-kali5-amd64
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
fi
|
|||
|
done
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Modifier la configuration pour prise en charge langue FR par défaut</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sed -i 's/hostname=kali/hostname=kali lang=fr_FR.UTF-8 locales=fr_FR.UTF-8 keyboard-layouts=fr keyboard-model=pc105/g' /mnt/multiboot/boot/grub/mbusb.d/kali.d/generic.cfg
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Log et mot de passe : kali</p>
|
|||
|
|
|||
|
<h3 id="partition-magic">Partition magic</h3>
|
|||
|
|
|||
|
<p>Montage fichier iso sur tmp</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir -p tmp
|
|||
|
sudo mount -o loop -t iso9660 pmagic_2019_12_24.iso tmp/
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Copie du répertoire <strong>pmagic</strong> sur la racine de la clé USB</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo cp -r tmp/pmagic/ /mnt/multiboot/ && sync
|
|||
|
sudo umount tmp
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Remplacer le fichier <strong>/mnt/multiboot/boot/grub/mbusb.d/pmagic.d/generic.cfg</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>submenu "Pmagic -->" {
|
|||
|
set default_settings="edd=on keymap=fr-latin1 fr_FR"
|
|||
|
set live_settings="boot=live eject=no"
|
|||
|
set linux_64="/pmagic/bzImage64"
|
|||
|
set linux_32="/pmagic/bzImage"
|
|||
|
set initrd_img="/pmagic/initrd.img /pmagic/fu.img /pmagic/m64.img"
|
|||
|
set initrd_img32="/pmagic/initrd.img /pmagic/fu.img /pmagic/m32.img"
|
|||
|
set message="Chargement kernel et initramfs. Patienter SVP..."
|
|||
|
|
|||
|
menuentry "Pmagic - Default settings 64 (Runs from RAM)"{
|
|||
|
echo $message
|
|||
|
search --set -f $linux_64
|
|||
|
linux $linux_64 $default_settings
|
|||
|
initrd $initrd_img
|
|||
|
}
|
|||
|
|
|||
|
menuentry "Pmagic - Default settings 32 (Runs from RAM)"{
|
|||
|
search --set -f $linux_32
|
|||
|
linux $linux_32 $default_settings
|
|||
|
initrd $initrd_img32
|
|||
|
}
|
|||
|
|
|||
|
menuentry "Pmagic - Live with default settings 64"{
|
|||
|
echo $message
|
|||
|
search --set -f $linux_64
|
|||
|
linux $linux_64 $default_settings $live_settings
|
|||
|
initrd $initrd_img
|
|||
|
}
|
|||
|
menuentry "Pmagic - Live with default settings 32"{
|
|||
|
search --set -f $linux_32
|
|||
|
linux $linux_32 $default_settings $live_settings
|
|||
|
initrd $initrd_img32
|
|||
|
}
|
|||
|
|
|||
|
menuentry "Pmagic - Clonezilla 64"{
|
|||
|
echo $message
|
|||
|
search --set -f $linux_64
|
|||
|
linux $linux_64 $default_settings clonezilla=yes
|
|||
|
initrd $initrd_img
|
|||
|
}
|
|||
|
menuentry "Pmagic - Clonezilla 32"{
|
|||
|
search --set -f $linux_32
|
|||
|
linux $linux_32 $default_settings clonezilla=yes
|
|||
|
initrd $initrd_img32
|
|||
|
}
|
|||
|
}
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="debian">Debian</h3>
|
|||
|
|
|||
|
<p>On monte l’image iso debian</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo mount -t iso9660 -o loop,ro iso/debian/bullseye/firmware-11.2.0-amd64-netinst.iso /mnt/iso
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Copier le dossier</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo rsync -avz --exclude "debian" /mnt/iso /mnt/multiboot/debian
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Créer le fichier <strong>/mnt/multiboot/boot/grub/mbusb.d/debian.d/generic.cfg</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>submenu "Debian 11 + Firmware -->" {
|
|||
|
|
|||
|
menuentry --hotkey=g 'Graphical install' {
|
|||
|
set background_color=black
|
|||
|
linux /debian/install.amd/vmlinuz vga=788 --- quiet
|
|||
|
initrd /debian/install.amd/gtk/initrd.gz
|
|||
|
}
|
|||
|
menuentry --hotkey=i 'Install' {
|
|||
|
set background_color=black
|
|||
|
linux /debian/install.amd/vmlinuz vga=788 --- quiet
|
|||
|
initrd /debian/install.amd/initrd.gz
|
|||
|
}
|
|||
|
}
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h2 id="démarrez-un-iso-avec-memdisk-facultatif">Démarrez un ISO avec MEMDISK (facultatif)</h2>
|
|||
|
|
|||
|
<p>[Using Syslinux’s MEMDISK][usingmemdisk], , un fichier ISO peut être chargé directement en mémoire (si le système en a assez), ce qui permettra de démarrer certaines images ISO non prises en charge.</p>
|
|||
|
|
|||
|
<p>Pour obtenir le fichier binaire de MEMDISK, vous pouvez installer <a href="">syslinux</a> à l’aide du gestionnaire de paquets de votre système et le trouver dans <code class="language-plaintext highlighter-rouge">/usr/lib/syslinux/memdisk</code> ou <code class="language-plaintext highlighter-rouge">/usr/lib/syslinux/bios/memdisk</code>, suivant votre distribution.</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo pacman -S syslinux # le fichier /usr/lib64/syslinux/bios/memdisk
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Alternativement, vous pouvez télécharger l’archive officielle depuis <a href="https://www.kernel.org/">kernel.org</a>, dans ce cas, vous trouverez le binaire <code class="language-plaintext highlighter-rouge">/bios/memdisk/memdisk</code>.</p>
|
|||
|
|
|||
|
<p>Une fois que vous avez le fichier, il suffit de le copier dans votre partition de données:</p>
|
|||
|
|
|||
|
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cp</span> <span class="nt">-f</span> /usr/lib64/syslinux/bios/memdisk /mnt/multiboot/boot/grub/
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Démontage</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo umount /mnt/multiboot
|
|||
|
sudo umount /mnt/multiboot/efi
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h2 id="test-périphérique-usb-avec-qemu">Test périphérique USB avec QEMU</h2>
|
|||
|
|
|||
|
<p>Pour tester le lecteur USB nouvellement créé dans un environnement virtuel, exécutez:</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo qemu-system-x86_64 -enable-kvm -rtc base=localtime -m 2G -vga std -drive file=/dev/sdd,readonly=on,cache=none,format=raw,if=virtio
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Remplacer <em>/dev/sdd</em> par le nom du périphérique USB (par exemple. <em>/dev/sdb,/dev/sdc,etc…</em>).<br />
|
|||
|
Exécutez <code class="language-plaintext highlighter-rouge">lsblk</code> pour obtenir cette information.</p>
|
|||
|
|
|||
|
<h2 id="annexe">Annexe</h2>
|
|||
|
|
|||
|
<h3 id="obtenir-des-fichiers-amorçables-iso">Obtenir des fichiers amorçables ISO</h3>
|
|||
|
|
|||
|
<p>Vous pouvez télécharger des fichiers ISO à partir de ces sites ,dans le dossier <code class="language-plaintext highlighter-rouge"><mountpoint>/boot/isos</code>:</p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li><strong><a href="https://antergos.com/">Antergos</a></strong>:un système d’exploitation moderne, élégant et puissant basé sur une des meilleures distributions Linux disponibles, Arch Linux.</li>
|
|||
|
<li><strong><a href="https://www.archlinux.org/">Arch Linux</a></strong>: une distribution légère et flexible de Linux® qui tente de rester simple.</li>
|
|||
|
<li><strong><a href="http://www.avg.com/ww-en/rescue-cd-business-edition">AVG Rescue CD</a></strong>:un outil pour réparer les pannes du système et permettre à vos systèmes de fonctionner à pleine capacité.</li>
|
|||
|
<li><strong><a href="https://backbox.org/">BackBox</a></strong>: une distribution basée sur Ubuntu développée pour effectuer des tests de pénétration et des évaluations de sécurité.</li>
|
|||
|
<li><strong><a href="http://www.centos.org/">CentOS</a></strong>: un effort de logiciel libre axé sur la communauté visant à fournir un écosystème open source robuste.</li>
|
|||
|
<li><strong><a href="http://clonezilla.org/clonezilla-live.php">Clonezilla Live</a></strong>: une petite distribution GNU/Linux pour le “clonage” des ordinateurs x86/amd64 (x86-64).</li>
|
|||
|
<li><strong><a href="https://www.debian.org/">Debian</a></strong>: un système d’exploitation gratuit (OS) pour votre ordinateur.</li>
|
|||
|
<li><strong><a href="https://elementary.io/">elementary OS</a></strong>: un remplacement rapide et ouvert pour Windows et OS X.</li>
|
|||
|
<li><strong><a href="https://getfedora.org/">Fedora</a></strong>: un système d’exploitation poli et facile à utiliser.</li>
|
|||
|
<li><strong><a href="https://www.gentoo.org/">Gentoo Linux</a></strong>: une distribution Linux souple et basée sur les sources.</li>
|
|||
|
<li><strong><a href="http://gparted.sourceforge.net/livecd.php">GParted Live</a></strong>: outil de partitionnement sur une distribution GNU/Linux.</li>
|
|||
|
<li><strong><a href="https://grml.org/">Grml Live Linux</a></strong>: un système live bootable basé sur Debian qui comprend une collection de logiciels GNU/Linux spécialement pour les administrateurs système.</li>
|
|||
|
<li><strong><a href="http://www.hirensbootcd.org/">Hiren’s BootCD</a></strong>: une trousse de premiers soins pour votre ordinateur.</li>
|
|||
|
<li><strong><a href="https://www.kali.org/">Kali Linux</a></strong>: une distribution Linux dérivée de Debian conçue pour le forensic numérique et les tests de pénétration.</li>
|
|||
|
<li><strong><a href="https://linuxmint.com/">Linux Mint</a></strong>: une distribution basée sur Ubuntu dont le but est de fournir une expérience complète en incluant des plugins de navigateur, des codecs multimédia, la prise en charge de la lecture de DVD, Java et autres Composants.</li>
|
|||
|
<li><strong><a href="https://manjaro.org/">Manjaro Linux</a></strong>: une distribution Linux conviviale basée sur le système d’exploitation Arch développé indépendamment.</li>
|
|||
|
<li><strong><a href="https://www.opensuse.org/">openSUSE</a></strong>: un projet et une distribution Linux sponsorisés par SUSE Linux GmbH et d’autres sociétés.</li>
|
|||
|
<li><strong><a href="https://www.parabola.nu/">Parabola GNU/Linux-libre</a></strong>: un effort communautaire pour fournir un système d’exploitation entièrement libre simple et léger.</li>
|
|||
|
<li><strong><a href="http://partedmagic.com/">Parted Magic</a></strong>: une solution complète de gestion des disques durs et plus encore.</li>
|
|||
|
<li><strong><a href="http://www.slax.org/">Slax Linux</a></strong>: un système d’exploitation Linux moderne, portable, petit et rapide avec une approche modulaire et un design exceptionnel.</li>
|
|||
|
<li><strong><a href="http://www.slitaz.org/">SliTaz</a></strong>: un système d’exploitation sécurisé et performant utilisant le noyau Linux et le logiciel GNU.</li>
|
|||
|
<li><strong><a href="http://www.sysresccd.org/">SystemRescueCd</a></strong>: une solution de secours de système Linux pour administrer ou réparer votre système et vos données après une panne.</li>
|
|||
|
<li><strong><a href="https://tails.boum.org/">Tails</a></strong>: un système d’exploitation en direct, qui vise à préserver votre vie privée et l’anonymat.</li>
|
|||
|
<li><strong><a href="https://trisquel.info/">Trisquel GNU/Linux</a></strong>: un système d’exploitation entièrement gratuit pour les particuliers, les petites entreprises et les centres éducatifs.</li>
|
|||
|
<li><strong><a href="http://www.ubuntu.com/">Ubuntu</a></strong>: une plateforme logicielle open source qui va du cloud, au smartphone.</li>
|
|||
|
<li><strong><a href="http://www.voidlinux.eu/">Void</a></strong>: un système d’exploitation à usage général, basé sur le noyau Linux® monolithique.</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<p>Vous pouvez obtenir des noyaux iPXE à partir de ces sites Web (sauvegardez sur <code class="language-plaintext highlighter-rouge"><mountpoint>/boot/krnl</code>):</p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li><strong><a href="http://boot.rackspace.com/">boot.rackspace.com</a></strong>: une collection de scripts iPXE qui vous permettent de rapidement redémarrer les systèmes d’exploitation, les utilitaires et d’autres outils très facilement.</li>
|
|||
|
<li><strong><a href="https://netboot.xyz/">netboot.xyz</a></strong>: un moyen de sélectionner les différents installateurs ou utilitaires du système d’exploitation à partir d’un emplacement dans le BIOS sans avoir besoin d’aller chercher le support pour exécuter l’outil.</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<h3 id="liens">Liens</h3>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li><a href="https://www.linuxbabe.com/desktop-linux/boot-from-iso-files-using-grub2-boot-loader">How to Boot ISO Files From GRUB2 Boot Loader</a></li>
|
|||
|
<li><a href="http://www.syslinux.org/wiki/index.php?title=MEMDISK">memdisk</a></li>
|
|||
|
<li><a href="http://www.syslinux.org/">syslinux</a></li>
|
|||
|
<li><a href="https://www.kernel.org/pub/linux/utils/boot/syslinux/">kernel.org</a></li>
|
|||
|
<li><a href="http://qemu.org/">qemu</a></li>
|
|||
|
<li><a href="https://wiki.archlinux.org/index.php/Multiboot_USB_drive#Using_Syslinux_and_memdisk">usingmemdisk</a></li>
|
|||
|
<li><a href="https://github.com/Thermionix/multipass-usb">multipass-usb</a></li>
|
|||
|
<li><a href="http://www.circuidipity.com/multi-boot-usb.html">multiboot-usb</a></li>
|
|||
|
<li><a href="http://www.panticz.de/MultiBootUSB">multibootusb</a></li>
|
|||
|
<li><a href="http://forums.kali.org/showthread.php?1025-Grub2-Loop-Boot-Solution">loop-boot</a></li>
|
|||
|
<li><a href="http://www.gtkdb.de/index_7_2627.html">grml-usb-stick</a></li>
|
|||
|
<li><a href="http://www.rodsbooks.com/gdisk/sgdisk.html">sgdisk</a></li>
|
|||
|
<li><a href="http://www.rodsbooks.com/gdisk/hybrid.html">hybridmbr</a></li>
|
|||
|
<li><a href="https://wiki.archlinux.org/index.php/Multiboot_USB_drive#Hybrid_UEFI_GPT_.2B_BIOS_GPT.2FMBR_boot">efi+bios</a></li>
|
|||
|
</ul>
|
|||
|
|
|||
|
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<div class="d-print-none"><footer class="article__footer"><meta itemprop="dateModified" content="2020-03-10T00:00:00+01:00"><!-- start custom article footer snippet -->
|
|||
|
|
|||
|
<!-- end custom article footer snippet -->
|
|||
|
<!--
|
|||
|
<div align="right"><a type="application/rss+xml" href="/feed.xml" title="S'abonner"><i class="fa fa-rss fa-2x"></i></a>
|
|||
|
|
|||
|
 </div>
|
|||
|
-->
|
|||
|
</footer>
|
|||
|
<div class="article__section-navigator clearfix"><div class="previous"><span>PRÉCÉDENT</span><a href="/2020/03/10/Docker-Debian-Buster.html">Docker + Docker Compose sur Debian, installation et utilisation</a></div><div class="next"><span>SUIVANT</span><a href="/2020/03/11/Ampache-logiciel-libre-de-streaming-audio.html">Ampache, logiciel libre de streaming audio</a></div></div></div>
|
|||
|
|
|||
|
</div>
|
|||
|
|
|||
|
<script>(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
$(function() {
|
|||
|
var $this ,$scroll;
|
|||
|
var $articleContent = $('.js-article-content');
|
|||
|
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
|
|||
|
var scroll = hasSidebar ? '.js-page-main' : 'html, body';
|
|||
|
$scroll = $(scroll);
|
|||
|
|
|||
|
$articleContent.find('.highlight').each(function() {
|
|||
|
$this = $(this);
|
|||
|
$this.attr('data-lang', $this.find('code').attr('data-lang'));
|
|||
|
});
|
|||
|
$articleContent.find('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]').each(function() {
|
|||
|
$this = $(this);
|
|||
|
$this.append($('<a class="anchor d-print-none" aria-hidden="true"></a>').html('<i class="fas fa-anchor"></i>'));
|
|||
|
});
|
|||
|
$articleContent.on('click', '.anchor', function() {
|
|||
|
$scroll.scrollToAnchor('#' + $(this).parent().attr('id'), 400);
|
|||
|
});
|
|||
|
});
|
|||
|
});
|
|||
|
})();
|
|||
|
</script>
|
|||
|
|
|||
|
</div><section class="page__comments d-print-none"></section></article><!-- start custom main bottom snippet -->
|
|||
|
<!-- end custom main bottom snippet -->
|
|||
|
</div>
|
|||
|
</div></div></div></div>
|
|||
|
</div><script>(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
var $body = $('body'), $window = $(window);
|
|||
|
var $pageRoot = $('.js-page-root'), $pageMain = $('.js-page-main');
|
|||
|
var activeCount = 0;
|
|||
|
function modal(options) {
|
|||
|
var $root = this, visible, onChange, hideWhenWindowScroll = false;
|
|||
|
var scrollTop;
|
|||
|
function setOptions(options) {
|
|||
|
var _options = options || {};
|
|||
|
visible = _options.initialVisible === undefined ? false : show;
|
|||
|
onChange = _options.onChange;
|
|||
|
hideWhenWindowScroll = _options.hideWhenWindowScroll;
|
|||
|
}
|
|||
|
function init() {
|
|||
|
setState(visible);
|
|||
|
}
|
|||
|
function setState(isShow) {
|
|||
|
if (isShow === visible) {
|
|||
|
return;
|
|||
|
}
|
|||
|
visible = isShow;
|
|||
|
if (visible) {
|
|||
|
activeCount++;
|
|||
|
scrollTop = $(window).scrollTop() || $pageMain.scrollTop();
|
|||
|
$root.addClass('modal--show');
|
|||
|
$pageMain.scrollTop(scrollTop);
|
|||
|
activeCount === 1 && ($pageRoot.addClass('show-modal'), $body.addClass('of-hidden'));
|
|||
|
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.on('scroll', hide);
|
|||
|
$window.on('keyup', handleKeyup);
|
|||
|
} else {
|
|||
|
activeCount > 0 && activeCount--;
|
|||
|
$root.removeClass('modal--show');
|
|||
|
$window.scrollTop(scrollTop);
|
|||
|
activeCount === 0 && ($pageRoot.removeClass('show-modal'), $body.removeClass('of-hidden'));
|
|||
|
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.off('scroll', hide);
|
|||
|
$window.off('keyup', handleKeyup);
|
|||
|
}
|
|||
|
onChange && onChange(visible);
|
|||
|
}
|
|||
|
function show() {
|
|||
|
setState(true);
|
|||
|
}
|
|||
|
function hide() {
|
|||
|
setState(false);
|
|||
|
}
|
|||
|
function handleKeyup(e) {
|
|||
|
// Char Code: 27 ESC
|
|||
|
if (e.which === 27) {
|
|||
|
hide();
|
|||
|
}
|
|||
|
}
|
|||
|
setOptions(options);
|
|||
|
init();
|
|||
|
return {
|
|||
|
show: show,
|
|||
|
hide: hide,
|
|||
|
$el: $root
|
|||
|
};
|
|||
|
}
|
|||
|
$.fn.modal = modal;
|
|||
|
});
|
|||
|
})();
|
|||
|
</script><div class="modal modal--overflow page__search-modal d-print-none js-page-search-modal"><script>
|
|||
|
(function () {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
// search panel
|
|||
|
var search = (window.search || (window.search = {}));
|
|||
|
var useDefaultSearchBox = window.useDefaultSearchBox === undefined ?
|
|||
|
true : window.useDefaultSearchBox ;
|
|||
|
|
|||
|
var $searchModal = $('.js-page-search-modal');
|
|||
|
var $searchToggle = $('.js-search-toggle');
|
|||
|
var searchModal = $searchModal.modal({ onChange: handleModalChange, hideWhenWindowScroll: true });
|
|||
|
var modalVisible = false;
|
|||
|
search.searchModal = searchModal;
|
|||
|
|
|||
|
var $searchBox = null;
|
|||
|
var $searchInput = null;
|
|||
|
var $searchClear = null;
|
|||
|
|
|||
|
function getModalVisible() {
|
|||
|
return modalVisible;
|
|||
|
}
|
|||
|
search.getModalVisible = getModalVisible;
|
|||
|
|
|||
|
function handleModalChange(visible) {
|
|||
|
modalVisible = visible;
|
|||
|
if (visible) {
|
|||
|
search.onShow && search.onShow();
|
|||
|
useDefaultSearchBox && $searchInput[0] && $searchInput[0].focus();
|
|||
|
} else {
|
|||
|
search.onShow && search.onHide();
|
|||
|
useDefaultSearchBox && $searchInput[0] && $searchInput[0].blur();
|
|||
|
setTimeout(function() {
|
|||
|
useDefaultSearchBox && ($searchInput.val(''), $searchBox.removeClass('not-empty'));
|
|||
|
search.clear && search.clear();
|
|||
|
window.pageAsideAffix && window.pageAsideAffix.refresh();
|
|||
|
}, 400);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
$searchToggle.on('click', function() {
|
|||
|
modalVisible ? searchModal.hide() : searchModal.show();
|
|||
|
});
|
|||
|
// Char Code: 83 S, 191 /
|
|||
|
$(window).on('keyup', function(e) {
|
|||
|
if (!modalVisible && !window.isFormElement(e.target || e.srcElement) && (e.which === 83 || e.which === 191)) {
|
|||
|
modalVisible || searchModal.show();
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
if (useDefaultSearchBox) {
|
|||
|
$searchBox = $('.js-search-box');
|
|||
|
$searchInput = $searchBox.children('input');
|
|||
|
$searchClear = $searchBox.children('.js-icon-clear');
|
|||
|
search.getSearchInput = function() {
|
|||
|
return $searchInput.get(0);
|
|||
|
};
|
|||
|
search.getVal = function() {
|
|||
|
return $searchInput.val();
|
|||
|
};
|
|||
|
search.setVal = function(val) {
|
|||
|
$searchInput.val(val);
|
|||
|
};
|
|||
|
|
|||
|
$searchInput.on('focus', function() {
|
|||
|
$(this).addClass('focus');
|
|||
|
});
|
|||
|
$searchInput.on('blur', function() {
|
|||
|
$(this).removeClass('focus');
|
|||
|
});
|
|||
|
$searchInput.on('input', window.throttle(function() {
|
|||
|
var val = $(this).val();
|
|||
|
if (val === '' || typeof val !== 'string') {
|
|||
|
search.clear && search.clear();
|
|||
|
} else {
|
|||
|
$searchBox.addClass('not-empty');
|
|||
|
search.onInputNotEmpty && search.onInputNotEmpty(val);
|
|||
|
}
|
|||
|
}, 400));
|
|||
|
$searchClear.on('click', function() {
|
|||
|
$searchInput.val(''); $searchBox.removeClass('not-empty');
|
|||
|
search.clear && search.clear();
|
|||
|
});
|
|||
|
}
|
|||
|
});
|
|||
|
})();
|
|||
|
</script><div class="search search--dark">
|
|||
|
<div class="main">
|
|||
|
<div class="search__header">Recherche</div>
|
|||
|
<div class="search-bar">
|
|||
|
<div class="search-box js-search-box">
|
|||
|
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
|
|||
|
<input id="search-input" type="text" />
|
|||
|
<div class="search-box__icon-clear js-icon-clear">
|
|||
|
<a><i class="fas fa-times"></i></a>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<button class="button button--theme-dark button--pill search__cancel js-search-toggle">
|
|||
|
Annuler</button>
|
|||
|
</div>
|
|||
|
<div id="results-container" class="search-result js-search-result"></div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<!-- Script pointing to search-script.js -->
|
|||
|
<script>/*!
|
|||
|
* Simple-Jekyll-Search
|
|||
|
* Copyright 2015-2020, Christian Fei
|
|||
|
* Licensed under the MIT License.
|
|||
|
*/
|
|||
|
|
|||
|
(function(){
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$Templater_7 = {
|
|||
|
compile: compile,
|
|||
|
setOptions: setOptions
|
|||
|
}
|
|||
|
|
|||
|
const options = {}
|
|||
|
options.pattern = /\{(.*?)\}/g
|
|||
|
options.template = ''
|
|||
|
options.middleware = function () {}
|
|||
|
|
|||
|
function setOptions (_options) {
|
|||
|
options.pattern = _options.pattern || options.pattern
|
|||
|
options.template = _options.template || options.template
|
|||
|
if (typeof _options.middleware === 'function') {
|
|||
|
options.middleware = _options.middleware
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function compile (data) {
|
|||
|
return options.template.replace(options.pattern, function (match, prop) {
|
|||
|
const value = options.middleware(prop, data[prop], options.template)
|
|||
|
if (typeof value !== 'undefined') {
|
|||
|
return value
|
|||
|
}
|
|||
|
return data[prop] || match
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
'use strict';
|
|||
|
|
|||
|
function fuzzysearch (needle, haystack) {
|
|||
|
var tlen = haystack.length;
|
|||
|
var qlen = needle.length;
|
|||
|
if (qlen > tlen) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
if (qlen === tlen) {
|
|||
|
return needle === haystack;
|
|||
|
}
|
|||
|
outer: for (var i = 0, j = 0; i < qlen; i++) {
|
|||
|
var nch = needle.charCodeAt(i);
|
|||
|
while (j < tlen) {
|
|||
|
if (haystack.charCodeAt(j++) === nch) {
|
|||
|
continue outer;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
var _$fuzzysearch_1 = fuzzysearch;
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
|
|||
|
|
|||
|
var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
|
|||
|
|
|||
|
function FuzzySearchStrategy () {
|
|||
|
this.matches = function (string, crit) {
|
|||
|
return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
|
|||
|
|
|||
|
function LiteralSearchStrategy () {
|
|||
|
this.matches = function (str, crit) {
|
|||
|
if (!str) return false
|
|||
|
|
|||
|
str = str.trim().toLowerCase()
|
|||
|
crit = crit.trim().toLowerCase()
|
|||
|
|
|||
|
return crit.split(' ').filter(function (word) {
|
|||
|
return str.indexOf(word) >= 0
|
|||
|
}).length === crit.split(' ').length
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$Repository_4 = {
|
|||
|
put: put,
|
|||
|
clear: clear,
|
|||
|
search: search,
|
|||
|
setOptions: __setOptions_4
|
|||
|
}
|
|||
|
|
|||
|
/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
|
|||
|
/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
|
|||
|
|
|||
|
function NoSort () {
|
|||
|
return 0
|
|||
|
}
|
|||
|
|
|||
|
const data = []
|
|||
|
let opt = {}
|
|||
|
|
|||
|
opt.fuzzy = false
|
|||
|
opt.limit = 10
|
|||
|
opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
|
|||
|
opt.sort = NoSort
|
|||
|
opt.exclude = []
|
|||
|
|
|||
|
function put (data) {
|
|||
|
if (isObject(data)) {
|
|||
|
return addObject(data)
|
|||
|
}
|
|||
|
if (isArray(data)) {
|
|||
|
return addArray(data)
|
|||
|
}
|
|||
|
return undefined
|
|||
|
}
|
|||
|
function clear () {
|
|||
|
data.length = 0
|
|||
|
return data
|
|||
|
}
|
|||
|
|
|||
|
function isObject (obj) {
|
|||
|
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
|
|||
|
}
|
|||
|
|
|||
|
function isArray (obj) {
|
|||
|
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
|
|||
|
}
|
|||
|
|
|||
|
function addObject (_data) {
|
|||
|
data.push(_data)
|
|||
|
return data
|
|||
|
}
|
|||
|
|
|||
|
function addArray (_data) {
|
|||
|
const added = []
|
|||
|
clear()
|
|||
|
for (let i = 0, len = _data.length; i < len; i++) {
|
|||
|
if (isObject(_data[i])) {
|
|||
|
added.push(addObject(_data[i]))
|
|||
|
}
|
|||
|
}
|
|||
|
return added
|
|||
|
}
|
|||
|
|
|||
|
function search (crit) {
|
|||
|
if (!crit) {
|
|||
|
return []
|
|||
|
}
|
|||
|
return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
|
|||
|
}
|
|||
|
|
|||
|
function __setOptions_4 (_opt) {
|
|||
|
opt = _opt || {}
|
|||
|
|
|||
|
opt.fuzzy = _opt.fuzzy || false
|
|||
|
opt.limit = _opt.limit || 10
|
|||
|
opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
|
|||
|
opt.sort = _opt.sort || NoSort
|
|||
|
opt.exclude = _opt.exclude || []
|
|||
|
}
|
|||
|
|
|||
|
function findMatches (data, crit, strategy, opt) {
|
|||
|
const matches = []
|
|||
|
for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
|
|||
|
const match = findMatchesInObject(data[i], crit, strategy, opt)
|
|||
|
if (match) {
|
|||
|
matches.push(match)
|
|||
|
}
|
|||
|
}
|
|||
|
return matches
|
|||
|
}
|
|||
|
|
|||
|
function findMatchesInObject (obj, crit, strategy, opt) {
|
|||
|
for (const key in obj) {
|
|||
|
if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
|
|||
|
return obj
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function isExcluded (term, excludedTerms) {
|
|||
|
for (let i = 0, len = excludedTerms.length; i < len; i++) {
|
|||
|
const excludedTerm = excludedTerms[i]
|
|||
|
if (new RegExp(excludedTerm).test(term)) {
|
|||
|
return true
|
|||
|
}
|
|||
|
}
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
/* globals ActiveXObject:false */
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$JSONLoader_2 = {
|
|||
|
load: load
|
|||
|
}
|
|||
|
|
|||
|
function load (location, callback) {
|
|||
|
const xhr = getXHR()
|
|||
|
xhr.open('GET', location, true)
|
|||
|
xhr.onreadystatechange = createStateChangeListener(xhr, callback)
|
|||
|
xhr.send()
|
|||
|
}
|
|||
|
|
|||
|
function createStateChangeListener (xhr, callback) {
|
|||
|
return function () {
|
|||
|
if (xhr.readyState === 4 && xhr.status === 200) {
|
|||
|
try {
|
|||
|
callback(null, JSON.parse(xhr.responseText))
|
|||
|
} catch (err) {
|
|||
|
callback(err, null)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function getXHR () {
|
|||
|
return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$OptionsValidator_3 = function OptionsValidator (params) {
|
|||
|
if (!validateParams(params)) {
|
|||
|
throw new Error('-- OptionsValidator: required options missing')
|
|||
|
}
|
|||
|
|
|||
|
if (!(this instanceof OptionsValidator)) {
|
|||
|
return new OptionsValidator(params)
|
|||
|
}
|
|||
|
|
|||
|
const requiredOptions = params.required
|
|||
|
|
|||
|
this.getRequiredOptions = function () {
|
|||
|
return requiredOptions
|
|||
|
}
|
|||
|
|
|||
|
this.validate = function (parameters) {
|
|||
|
const errors = []
|
|||
|
requiredOptions.forEach(function (requiredOptionName) {
|
|||
|
if (typeof parameters[requiredOptionName] === 'undefined') {
|
|||
|
errors.push(requiredOptionName)
|
|||
|
}
|
|||
|
})
|
|||
|
return errors
|
|||
|
}
|
|||
|
|
|||
|
function validateParams (params) {
|
|||
|
if (!params) {
|
|||
|
return false
|
|||
|
}
|
|||
|
return typeof params.required !== 'undefined' && params.required instanceof Array
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$utils_9 = {
|
|||
|
merge: merge,
|
|||
|
isJSON: isJSON
|
|||
|
}
|
|||
|
|
|||
|
function merge (defaultParams, mergeParams) {
|
|||
|
const mergedOptions = {}
|
|||
|
for (const option in defaultParams) {
|
|||
|
mergedOptions[option] = defaultParams[option]
|
|||
|
if (typeof mergeParams[option] !== 'undefined') {
|
|||
|
mergedOptions[option] = mergeParams[option]
|
|||
|
}
|
|||
|
}
|
|||
|
return mergedOptions
|
|||
|
}
|
|||
|
|
|||
|
function isJSON (json) {
|
|||
|
try {
|
|||
|
if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
|
|||
|
return true
|
|||
|
}
|
|||
|
return false
|
|||
|
} catch (err) {
|
|||
|
return false
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
var _$src_8 = {};
|
|||
|
(function (window) {
|
|||
|
'use strict'
|
|||
|
|
|||
|
let options = {
|
|||
|
searchInput: null,
|
|||
|
resultsContainer: null,
|
|||
|
json: [],
|
|||
|
success: Function.prototype,
|
|||
|
searchResultTemplate: '<li><a href="{url}" title="{desc}">{title}</a></li>',
|
|||
|
templateMiddleware: Function.prototype,
|
|||
|
sortMiddleware: function () {
|
|||
|
return 0
|
|||
|
},
|
|||
|
noResultsText: 'No results found',
|
|||
|
limit: 10,
|
|||
|
fuzzy: false,
|
|||
|
debounceTime: null,
|
|||
|
exclude: []
|
|||
|
}
|
|||
|
|
|||
|
let debounceTimerHandle
|
|||
|
const debounce = function (func, delayMillis) {
|
|||
|
if (delayMillis) {
|
|||
|
clearTimeout(debounceTimerHandle)
|
|||
|
debounceTimerHandle = setTimeout(func, delayMillis)
|
|||
|
} else {
|
|||
|
func.call()
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const requiredOptions = ['searchInput', 'resultsContainer', 'json']
|
|||
|
|
|||
|
/* removed: const _$Templater_7 = require('./Templater') */;
|
|||
|
/* removed: const _$Repository_4 = require('./Repository') */;
|
|||
|
/* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
|
|||
|
const optionsValidator = _$OptionsValidator_3({
|
|||
|
required: requiredOptions
|
|||
|
})
|
|||
|
/* removed: const _$utils_9 = require('./utils') */;
|
|||
|
|
|||
|
window.SimpleJekyllSearch = function (_options) {
|
|||
|
const errors = optionsValidator.validate(_options)
|
|||
|
if (errors.length > 0) {
|
|||
|
throwError('You must specify the following required options: ' + requiredOptions)
|
|||
|
}
|
|||
|
|
|||
|
options = _$utils_9.merge(options, _options)
|
|||
|
|
|||
|
_$Templater_7.setOptions({
|
|||
|
template: options.searchResultTemplate,
|
|||
|
middleware: options.templateMiddleware
|
|||
|
})
|
|||
|
|
|||
|
_$Repository_4.setOptions({
|
|||
|
fuzzy: options.fuzzy,
|
|||
|
limit: options.limit,
|
|||
|
sort: options.sortMiddleware,
|
|||
|
exclude: options.exclude
|
|||
|
})
|
|||
|
|
|||
|
if (_$utils_9.isJSON(options.json)) {
|
|||
|
initWithJSON(options.json)
|
|||
|
} else {
|
|||
|
initWithURL(options.json)
|
|||
|
}
|
|||
|
|
|||
|
const rv = {
|
|||
|
search: search
|
|||
|
}
|
|||
|
|
|||
|
typeof options.success === 'function' && options.success.call(rv)
|
|||
|
return rv
|
|||
|
}
|
|||
|
|
|||
|
function initWithJSON (json) {
|
|||
|
_$Repository_4.put(json)
|
|||
|
registerInput()
|
|||
|
}
|
|||
|
|
|||
|
function initWithURL (url) {
|
|||
|
_$JSONLoader_2.load(url, function (err, json) {
|
|||
|
if (err) {
|
|||
|
throwError('failed to get JSON (' + url + ')')
|
|||
|
}
|
|||
|
initWithJSON(json)
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
function emptyResultsContainer () {
|
|||
|
options.resultsContainer.innerHTML = ''
|
|||
|
}
|
|||
|
|
|||
|
function appendToResultsContainer (text) {
|
|||
|
options.resultsContainer.innerHTML += text
|
|||
|
}
|
|||
|
|
|||
|
function registerInput () {
|
|||
|
options.searchInput.addEventListener('input', function (e) {
|
|||
|
if (isWhitelistedKey(e.which)) {
|
|||
|
emptyResultsContainer()
|
|||
|
debounce(function () { search(e.target.value) }, options.debounceTime)
|
|||
|
}
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
function search (query) {
|
|||
|
if (isValidQuery(query)) {
|
|||
|
emptyResultsContainer()
|
|||
|
render(_$Repository_4.search(query), query)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function render (results, query) {
|
|||
|
const len = results.length
|
|||
|
if (len === 0) {
|
|||
|
return appendToResultsContainer(options.noResultsText)
|
|||
|
}
|
|||
|
for (let i = 0; i < len; i++) {
|
|||
|
results[i].query = query
|
|||
|
appendToResultsContainer(_$Templater_7.compile(results[i]))
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function isValidQuery (query) {
|
|||
|
return query && query.length > 0
|
|||
|
}
|
|||
|
|
|||
|
function isWhitelistedKey (key) {
|
|||
|
return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
|
|||
|
}
|
|||
|
|
|||
|
function throwError (message) {
|
|||
|
throw new Error('SimpleJekyllSearch --- ' + message)
|
|||
|
}
|
|||
|
})(window)
|
|||
|
|
|||
|
}());
|
|||
|
</script>
|
|||
|
|
|||
|
<!-- Configuration -->
|
|||
|
<script>
|
|||
|
SimpleJekyllSearch({
|
|||
|
searchInput: document.getElementById('search-input'),
|
|||
|
resultsContainer: document.getElementById('results-container'),
|
|||
|
noResultsText: '<p>Aucun résultat!</p>',
|
|||
|
json: '/search.json',
|
|||
|
searchResultTemplate: '<li><a href="{url}">{date} {title}</a> (Création {create})</li>'
|
|||
|
})
|
|||
|
</script>
|
|||
|
|
|||
|
</div></div>
|
|||
|
|
|||
|
|
|||
|
<script>(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
function scrollToAnchor(anchor, duration, callback) {
|
|||
|
var $root = this;
|
|||
|
$root.animate({ scrollTop: $(anchor).position().top }, duration, function() {
|
|||
|
window.history.replaceState(null, '', window.location.href.split('#')[0] + anchor);
|
|||
|
callback && callback();
|
|||
|
});
|
|||
|
}
|
|||
|
$.fn.scrollToAnchor = scrollToAnchor;
|
|||
|
});
|
|||
|
})();
|
|||
|
(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
function affix(options) {
|
|||
|
var $root = this, $window = $(window), $scrollTarget, $scroll,
|
|||
|
offsetBottom = 0, scrollTarget = window, scroll = window.document, disabled = false, isOverallScroller = true,
|
|||
|
rootTop, rootLeft, rootHeight, scrollBottom, rootBottomTop,
|
|||
|
hasInit = false, curState;
|
|||
|
|
|||
|
function setOptions(options) {
|
|||
|
var _options = options || {};
|
|||
|
_options.offsetBottom && (offsetBottom = _options.offsetBottom);
|
|||
|
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
|
|||
|
_options.scroll && (scroll = _options.scroll);
|
|||
|
_options.disabled !== undefined && (disabled = _options.disabled);
|
|||
|
$scrollTarget = $(scrollTarget);
|
|||
|
isOverallScroller = window.isOverallScroller($scrollTarget[0]);
|
|||
|
$scroll = $(scroll);
|
|||
|
}
|
|||
|
function preCalc() {
|
|||
|
top();
|
|||
|
rootHeight = $root.outerHeight();
|
|||
|
rootTop = $root.offset().top + (isOverallScroller ? 0 : $scrollTarget.scrollTop());
|
|||
|
rootLeft = $root.offset().left;
|
|||
|
}
|
|||
|
function calc(needPreCalc) {
|
|||
|
needPreCalc && preCalc();
|
|||
|
scrollBottom = $scroll.outerHeight() - offsetBottom - rootHeight;
|
|||
|
rootBottomTop = scrollBottom - rootTop;
|
|||
|
}
|
|||
|
function top() {
|
|||
|
if (curState !== 'top') {
|
|||
|
$root.removeClass('fixed').css({
|
|||
|
left: 0,
|
|||
|
top: 0
|
|||
|
});
|
|||
|
curState = 'top';
|
|||
|
}
|
|||
|
}
|
|||
|
function fixed() {
|
|||
|
if (curState !== 'fixed') {
|
|||
|
$root.addClass('fixed').css({
|
|||
|
left: rootLeft + 'px',
|
|||
|
top: 0
|
|||
|
});
|
|||
|
curState = 'fixed';
|
|||
|
}
|
|||
|
}
|
|||
|
function bottom() {
|
|||
|
if (curState !== 'bottom') {
|
|||
|
$root.removeClass('fixed').css({
|
|||
|
left: 0,
|
|||
|
top: rootBottomTop + 'px'
|
|||
|
});
|
|||
|
curState = 'bottom';
|
|||
|
}
|
|||
|
}
|
|||
|
function setState() {
|
|||
|
var scrollTop = $scrollTarget.scrollTop();
|
|||
|
if (scrollTop >= rootTop && scrollTop <= scrollBottom) {
|
|||
|
fixed();
|
|||
|
} else if (scrollTop < rootTop) {
|
|||
|
top();
|
|||
|
} else {
|
|||
|
bottom();
|
|||
|
}
|
|||
|
}
|
|||
|
function init() {
|
|||
|
if(!hasInit) {
|
|||
|
var interval, timeout;
|
|||
|
calc(true); setState();
|
|||
|
// run calc every 100 millisecond
|
|||
|
interval = setInterval(function() {
|
|||
|
calc();
|
|||
|
}, 100);
|
|||
|
timeout = setTimeout(function() {
|
|||
|
clearInterval(interval);
|
|||
|
}, 45000);
|
|||
|
window.pageLoad.then(function() {
|
|||
|
setTimeout(function() {
|
|||
|
clearInterval(interval);
|
|||
|
clearTimeout(timeout);
|
|||
|
}, 3000);
|
|||
|
});
|
|||
|
$scrollTarget.on('scroll', function() {
|
|||
|
disabled || setState();
|
|||
|
});
|
|||
|
$window.on('resize', function() {
|
|||
|
disabled || (calc(true), setState());
|
|||
|
});
|
|||
|
hasInit = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
setOptions(options);
|
|||
|
if (!disabled) {
|
|||
|
init();
|
|||
|
}
|
|||
|
$window.on('resize', window.throttle(function() {
|
|||
|
init();
|
|||
|
}, 200));
|
|||
|
return {
|
|||
|
setOptions: setOptions,
|
|||
|
refresh: function() {
|
|||
|
calc(true, { animation: false }); setState();
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
$.fn.affix = affix;
|
|||
|
});
|
|||
|
})();
|
|||
|
(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
function toc(options) {
|
|||
|
var $root = this, $window = $(window), $scrollTarget, $scroller, $tocUl = $('<ul class="toc toc--ellipsis"></ul>'), $tocLi, $headings, $activeLast, $activeCur,
|
|||
|
selectors = 'h1,h2,h3', container = 'body', scrollTarget = window, scroller = 'html, body', disabled = false,
|
|||
|
headingsPos, scrolling = false, hasRendered = false, hasInit = false;
|
|||
|
|
|||
|
function setOptions(options) {
|
|||
|
var _options = options || {};
|
|||
|
_options.selectors && (selectors = _options.selectors);
|
|||
|
_options.container && (container = _options.container);
|
|||
|
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
|
|||
|
_options.scroller && (scroller = _options.scroller);
|
|||
|
_options.disabled !== undefined && (disabled = _options.disabled);
|
|||
|
$headings = $(container).find(selectors).filter('[id]');
|
|||
|
$scrollTarget = $(scrollTarget);
|
|||
|
$scroller = $(scroller);
|
|||
|
}
|
|||
|
function calc() {
|
|||
|
headingsPos = [];
|
|||
|
$headings.each(function() {
|
|||
|
headingsPos.push(Math.floor($(this).position().top));
|
|||
|
});
|
|||
|
}
|
|||
|
function setState(element, disabled) {
|
|||
|
var scrollTop = $scrollTarget.scrollTop(), i;
|
|||
|
if (disabled || !headingsPos || headingsPos.length < 1) { return; }
|
|||
|
if (element) {
|
|||
|
$activeCur = element;
|
|||
|
} else {
|
|||
|
for (i = 0; i < headingsPos.length; i++) {
|
|||
|
if (scrollTop >= headingsPos[i]) {
|
|||
|
$activeCur = $tocLi.eq(i);
|
|||
|
} else {
|
|||
|
$activeCur || ($activeCur = $tocLi.eq(i));
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
$activeLast && $activeLast.removeClass('active');
|
|||
|
($activeLast = $activeCur).addClass('active');
|
|||
|
}
|
|||
|
function render() {
|
|||
|
if(!hasRendered) {
|
|||
|
$root.append($tocUl);
|
|||
|
$headings.each(function() {
|
|||
|
var $this = $(this);
|
|||
|
$tocUl.append($('<li></li>').addClass('toc-' + $this.prop('tagName').toLowerCase())
|
|||
|
.append($('<a></a>').text($this.text()).attr('href', '#' + $this.prop('id'))));
|
|||
|
});
|
|||
|
$tocLi = $tocUl.children('li');
|
|||
|
$tocUl.on('click', 'a', function(e) {
|
|||
|
e.preventDefault();
|
|||
|
var $this = $(this);
|
|||
|
scrolling = true;
|
|||
|
setState($this.parent());
|
|||
|
$scroller.scrollToAnchor($this.attr('href'), 400, function() {
|
|||
|
scrolling = false;
|
|||
|
});
|
|||
|
});
|
|||
|
}
|
|||
|
hasRendered = true;
|
|||
|
}
|
|||
|
function init() {
|
|||
|
var interval, timeout;
|
|||
|
if(!hasInit) {
|
|||
|
render(); calc(); setState(null, scrolling);
|
|||
|
// run calc every 100 millisecond
|
|||
|
interval = setInterval(function() {
|
|||
|
calc();
|
|||
|
}, 100);
|
|||
|
timeout = setTimeout(function() {
|
|||
|
clearInterval(interval);
|
|||
|
}, 45000);
|
|||
|
window.pageLoad.then(function() {
|
|||
|
setTimeout(function() {
|
|||
|
clearInterval(interval);
|
|||
|
clearTimeout(timeout);
|
|||
|
}, 3000);
|
|||
|
});
|
|||
|
$scrollTarget.on('scroll', function() {
|
|||
|
disabled || setState(null, scrolling);
|
|||
|
});
|
|||
|
$window.on('resize', window.throttle(function() {
|
|||
|
if (!disabled) {
|
|||
|
render(); calc(); setState(null, scrolling);
|
|||
|
}
|
|||
|
}, 100));
|
|||
|
}
|
|||
|
hasInit = true;
|
|||
|
}
|
|||
|
|
|||
|
setOptions(options);
|
|||
|
if (!disabled) {
|
|||
|
init();
|
|||
|
}
|
|||
|
$window.on('resize', window.throttle(function() {
|
|||
|
init();
|
|||
|
}, 200));
|
|||
|
return {
|
|||
|
setOptions: setOptions
|
|||
|
};
|
|||
|
}
|
|||
|
$.fn.toc = toc;
|
|||
|
});
|
|||
|
})();
|
|||
|
/*(function () {
|
|||
|
|
|||
|
})();*/
|
|||
|
</script><script>
|
|||
|
/* toc must before affix, since affix need to konw toc' height. */(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
var TOC_SELECTOR = window.TEXT_VARIABLES.site.toc.selectors;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
var $window = $(window);
|
|||
|
var $articleContent = $('.js-article-content');
|
|||
|
var $tocRoot = $('.js-toc-root'), $col2 = $('.js-col-aside');
|
|||
|
var toc;
|
|||
|
var tocDisabled = false;
|
|||
|
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
|
|||
|
var hasToc = $articleContent.find(TOC_SELECTOR).length > 0;
|
|||
|
|
|||
|
function disabled() {
|
|||
|
return $col2.css('display') === 'none' || !hasToc;
|
|||
|
}
|
|||
|
|
|||
|
tocDisabled = disabled();
|
|||
|
|
|||
|
toc = $tocRoot.toc({
|
|||
|
selectors: TOC_SELECTOR,
|
|||
|
container: $articleContent,
|
|||
|
scrollTarget: hasSidebar ? '.js-page-main' : null,
|
|||
|
scroller: hasSidebar ? '.js-page-main' : null,
|
|||
|
disabled: tocDisabled
|
|||
|
});
|
|||
|
|
|||
|
$window.on('resize', window.throttle(function() {
|
|||
|
tocDisabled = disabled();
|
|||
|
toc && toc.setOptions({
|
|||
|
disabled: tocDisabled
|
|||
|
});
|
|||
|
}, 100));
|
|||
|
|
|||
|
});
|
|||
|
})();
|
|||
|
(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
var $window = $(window), $pageFooter = $('.js-page-footer');
|
|||
|
var $pageAside = $('.js-page-aside');
|
|||
|
var affix;
|
|||
|
var tocDisabled = false;
|
|||
|
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
|
|||
|
|
|||
|
affix = $pageAside.affix({
|
|||
|
offsetBottom: $pageFooter.outerHeight(),
|
|||
|
scrollTarget: hasSidebar ? '.js-page-main' : null,
|
|||
|
scroller: hasSidebar ? '.js-page-main' : null,
|
|||
|
scroll: hasSidebar ? $('.js-page-main').children() : null,
|
|||
|
disabled: tocDisabled
|
|||
|
});
|
|||
|
|
|||
|
$window.on('resize', window.throttle(function() {
|
|||
|
affix && affix.setOptions({
|
|||
|
disabled: tocDisabled
|
|||
|
});
|
|||
|
}, 100));
|
|||
|
|
|||
|
window.pageAsideAffix = affix;
|
|||
|
});
|
|||
|
})();
|
|||
|
</script><!---->
|
|||
|
|
|||
|
</div>
|
|||
|
<script>(function () {
|
|||
|
var $root = document.getElementsByClassName('root')[0];
|
|||
|
if (window.hasEvent('touchstart')) {
|
|||
|
$root.dataset.isTouch = true;
|
|||
|
document.addEventListener('touchstart', function(){}, false);
|
|||
|
}
|
|||
|
})();
|
|||
|
</script>
|
|||
|
</body>
|
|||
|
</html>
|
|||
|
|