| Omitir Vínculos de navegación | |
| Salir de la Vista de impresión | |
|
Guía de administración de Oracle® ZFS Storage Appliance |
Capítulo 1 Descripción general de Oracle ZFS Storage Appliance
Capítulo 3 Configuración inicial
Capítulo 4 Configuración de red
Capítulo 5 Configuración del almacenamiento
Capítulo 6 Configuración de red de área de almacenamiento
Capítulo 7 Configuración de usuario
Capítulo 8 Configuración de preferencias de dispositivos ZFSSA
Capítulo 9 Configuración de alertas
Capítulo 10 Configuración de cluster
Capítulo 11 Servicios del dispositivo ZFSSA
Capítulo 12 Recursos compartidos, proyectos y esquemas
Capítulo 15 Secuencias de comandos de la CLI
Creación de secuencias de comandos
Entorno de secuencia de comandos
Desde luego, las secuencias de comandos sirven de poco si no pueden interactuar con el sistema en general. Hay varias funciones incorporadas que permiten a las secuencias de comandos interactuar con el sistema:
|
La manera más simple para que las secuencias de comandos interaccionen con el sistema es utilizar la función "run": toma un comando para ejecutarlo y devuelve la salida de ese comando como una cadena. Por ejemplo:
dory:> configuration version script dump(run('get boot_time'))
' boot_time = 2009-10-12 07:02:17\n'
La función incorporada dump vuelca el argumento, sin expandir ninguna de las nuevas líneas incrustadas. Se pueden usar las características de manipulación de cadenas de ECMAScript para separar la salida. Por ejemplo, si se divide lo anterior en función de los espacios en blanco:
dory:> configuration version script dump(run('get boot_time').split(/\s+/))
['', 'boot_time', '=', '2009-10-12', '07:02:17', '']
Como la función run es potente, puede resultar tentador recurrir solamente al análisis de la salida para obtener información del sistema, pero esto tiene la desventaja de que deja salidas de análisis de secuencias de comandos legibles para el ojo humano, que pueden cambiar o no en el futuro. Para recopilar información del sistema de manera más robusta, use la función "get" incorporada. En el caso de la propiedad boot_time, no devuelve la cadena, sino que devuelve el objeto Date de ECMAScript, que permite la manipulación del valor de la propiedad mediante programación. Por ejemplo, tal vez desee usar la propiedad boot_time en combinación con la hora actual para determinar el tiempo transcurrido desde el inicio:
script
run('configuration version');
now = new Date();
uptime = (now.valueOf() - get('boot_time').valueOf()) / 1000;
printf('up %d day%s, %d hour%s, %d minute%s, %d second%s\n',
d = uptime / 86400, d < 1 || d >= 2 ? 's' : '',
h = (uptime / 3600) % 24, h < 1 || h >= 2 ? 's': '',
m = (uptime / 60) % 60, m < 1 || m >= 2 ? 's': '',
s = uptime % 60, s < 1 || s >= 2 ? 's': '');
Suponiendo que lo anterior se guarda como "uptime.aksh", lo puede ejecutar de la siguiente manera:
% ssh root@dory < uptime.aksh Pseudo-terminal will not be allocated because stdin is not a terminal. Password: up 2 days, 10 hours, 47 minutes, 48 seconds
El mensaje sobre la asignación pseudoterminal se debe al cliente ssh; para solucionar el problema al que hace referencia este mensaje se puede especificar la opción "-T" para ssh.
En un contexto con elementos secundarios dinámicos, puede resultar muy útil iterar entre esos elementos secundarios mediante programación. Para ello se puede utilizar la función list, que devuelve una matriz de elementos secundarios dinámicos. Por ejemplo, a continuación, se muestra una secuencia de comandos que itera todos los recursos compartidos de cada proyecto e imprime la cantidad de espacio consumido y el espacio disponible:
script
run('shares');
projects = list();
for (i = 0; i < projects.length; i++) {
run('select ' + projects[i]);
shares = list();
for (j = 0; j < shares.length; j++) {
run('select ' + shares[j]);
printf("%s/%s %1.64g %1.64g\n", projects[i], shares[j],
get('space_data'), get('space_available'));
run('cd ..');
}
run('cd ..');
}
Ésta es la salida de la ejecución de la secuencia de comandos, suponiendo que se haya guardado en un archivo llamado "space.aksh":
% ssh root@koi < space.aksh Password: admin/accounts 18432 266617007104 admin/exports 18432 266617007104 admin/primary 18432 266617007104 admin/traffic 18432 266617007104 admin/workflow 18432 266617007104 aleventhal/hw_eng 18432 266617007104 bcantrill/analytx 1073964032 266617007104 bgregg/dashbd 18432 266617007104 bgregg/filesys01 26112 107374156288 bpijewski/access_ctrl 18432 266617007104 ...
Si se deseara una variante más "estética" (si bien sería más difícil desde el punto de vista de la programación), se puede analizar directamente la salida del comando get:
script
run('shares');
projects = list();
printf('%-40s %-10s %-10s\n', 'SHARE', 'USED', 'AVAILABLE');
for (i = 0; i < projects.length; i++) {
run('select ' + projects[i]);
shares = list();
for (j = 0; j < shares.length; j++) {
run('select ' + shares[j]);
share = projects[i] + '/' + shares[j];
used = run('get space_data').split(/\s+/)[3];
avail = run('get space_available').split(/\s+/)[3];
printf('%-40s %-10s %-10s\n', share, used, avail);
run('cd ..');
}
run('cd ..');
}
Y ésta es la salida de la ejecución de esta nueva secuencia de comandos, suponiendo que se le asignó el nombre "prettyspace.aksh":
% ssh root@koi < prettyspace.aksh Password: SHARE USED AVAILABLE admin/accounts 18K 248G admin/exports 18K 248G admin/primary 18K 248G admin/traffic 18K 248G admin/workflow 18K 248G aleventhal/hw_eng 18K 248G bcantrill/analytx 1.00G 248G bgregg/dashbd 18K 248G bgregg/filesys01 25.5K 100G bpijewski/access_ctrl 18K 248G ...
Incluso en un contexto con elementos secundarios estáticos, puede resultar útil iterar entre esos elementos secundarios mediante programación. Para ello se puede utilizar la función children, que devuelve una matriz de elementos secundarios estáticos. Por ejemplo, esta secuencia de comandos itera cada servicio e imprime el estado correspondiente:
configuration services
script
var svcs = children();
for (var i = 0; i < svcs.length; ++i) {
run(svcs[i]);
try {
printf("%-10s %s\n", svcs[i], get('<status>'));
} catch (err) { }
run("done");
}
Ésta es la salida de la ejecución de la secuencia de comandos, suponiendo que se haya guardado en un archivo llamado "svcinfo.aksh":
% ssh root@koi < space.aksh Password: cifs disabled dns online ftp disabled http disabled identity online idmap online ipmp online iscsi online ldap disabled ndmp online nfs online nis online ntp online scrk online sftp disabled smtp online snmp disabled ssh online tags online vscan disabled
La función choices devuelve una selección de los valores válidos de cualquier propiedad para la cual se conoce el conjunto de valores y se puede enumerar. Por ejemplo, la siguiente secuencia de comandos recupera la lista de todas las agrupaciones en el nodo de recursos compartidos mediante la función choices y, luego, itera todas las agrupaciones para enumerar los proyectos y recursos compartidos junto con el espacio disponible.
fmt = '%-40s %-15s %-15s\n';
printf(fmt, 'SHARE', 'USED', 'AVAILABLE');
run('cd /');
run('shares');
pools = choices('pool');
for (p = 0; p < pools.length; p++) {
set('pool', pools[p]);
projects = list();
for (i = 0; i < projects.length; i++) {
run('select ' + projects[i]);
shares = list();
for (j = 0; j < shares.length; j++) {
run('select ' + shares[j]);
share = pools[p] + ':' + projects[i] + '/' + shares[j];
printf(fmt, share, get('space_data'),
get('space_available'));
run('cd ..');
}
run('cd ..');
}
}
Esta es la salida de la ejecución de la secuencia de comandos:
SHARE USED AVAILABLE pond:projectA/fs1 31744 566196178944 pond:projectA/fs2 31744 566196178944 pond:projectB/lun1 21474836480 587670999040 puddle:deptA/share1 238475 467539219283 puddle:deptB/share1 129564 467539219283 puddle:deptB/share2 19283747 467539219283