modul Etc
Das Modul Etc bietet Zugriff auf Informationen, die typischerweise in Dateien im Verzeichnis /etc auf Unix-Systemen gespeichert sind.
Die zugänglichen Informationen umfassen die in den Dateien /etc/passwd und /etc/group gefundenen Informationen, sowie Informationen über das temporäre Verzeichnis des Systems (/tmp) und das Konfigurationsverzeichnis (/etc).
Das Modul Etc bietet eine zuverlässigere Möglichkeit, auf Informationen über den angemeldeten Benutzer zuzugreifen, als Umgebungsvariablen wie +$USER+.
Beispiel
require 'etc' login = Etc.getlogin info = Etc.getpwnam(login) username = info.gecos.split(/,/).first puts "Hello #{username}, I see your login name is #{login}"
Beachten Sie, dass die von diesem Modul bereitgestellten Methoden nicht immer sicher sind. Sie sollten für Informationszwecke und nicht für Sicherheitszwecke verwendet werden.
Alle in diesem Modul definierten Operationen sind Klassenmethoden, sodass Sie das Modul Etc in Ihre Klasse einbinden können.
Constants
- VERSION
-
Die Version
Öffentliche Klassenmethoden
Source
static VALUE
etc_confstr(VALUE obj, VALUE arg)
{
int name;
char localbuf[128], *buf = localbuf;
size_t bufsize = sizeof(localbuf), ret;
VALUE tmp;
name = NUM2INT(arg);
errno = 0;
ret = confstr(name, buf, bufsize);
if (bufsize < ret) {
bufsize = ret;
buf = ALLOCV_N(char, tmp, bufsize);
errno = 0;
ret = confstr(name, buf, bufsize);
}
if (bufsize < ret)
rb_bug("required buffer size for confstr() changed dynamically.");
if (ret == 0) {
if (errno == 0) /* no configuration-defined value */
return Qnil;
rb_sys_fail("confstr");
}
return rb_str_new_cstr(buf);
}
Gibt eine Systemkonfigurationsvariable mithilfe von confstr() zurück.
name sollte eine Konstante unter Etc sein, die mit CS_ beginnt.
Der Rückgabewert ist ein String oder nil. nil bedeutet kein konfigurationsdefinierten Wert. (confstr() gibt 0 zurück, aber errno wird nicht gesetzt.)
Etc.confstr(Etc::CS_PATH) #=> "/bin:/usr/bin" # GNU/Linux Etc.confstr(Etc::CS_GNU_LIBC_VERSION) #=> "glibc 2.18" Etc.confstr(Etc::CS_GNU_LIBPTHREAD_VERSION) #=> "NPTL 2.18"
Source
static VALUE
etc_endgrent(VALUE obj)
{
#ifdef HAVE_GETGRENT
endgrent();
#endif
return Qnil;
}
Beendet den Prozess des Durchsuchens der Datei /etc/group, der durch ::getgrent begonnen wurde, und schließt die Datei.
Source
static VALUE
etc_endpwent(VALUE obj)
{
#ifdef HAVE_GETPWENT
endpwent();
#endif
return Qnil;
}
Beendet den Prozess des Durchsuchens der Datei /etc/passwd, der mit ::getpwent begonnen wurde, und schließt die Datei.
Source
static VALUE
etc_getgrent(VALUE obj)
{
#ifdef HAVE_GETGRENT
struct group *gr;
if ((gr = getgrent()) != 0) {
return setup_group(gr);
}
#endif
return Qnil;
}
Gibt einen Eintrag aus der Datei /etc/group zurück.
Beim ersten Aufruf wird die Datei geöffnet und der erste Eintrag zurückgegeben; jeder nachfolgende Aufruf gibt den nächsten Eintrag zurück oder nil, wenn das Ende der Datei erreicht ist.
Um die Datei nach Abschluss der Verarbeitung zu schließen, rufen Sie ::endgrent auf.
Jeder Eintrag wird als Group-Struktur zurückgegeben
Source
static VALUE
etc_getgrgid(int argc, VALUE *argv, VALUE obj)
{
#ifdef HAVE_GETGRENT
VALUE id;
gid_t gid;
struct group *grp;
if (rb_scan_args(argc, argv, "01", &id) == 1) {
gid = NUM2GIDT(id);
}
else {
gid = getgid();
}
grp = getgrgid(gid);
if (grp == 0) rb_raise(rb_eArgError, "can't find group for %d", (int)gid);
return setup_group(grp);
#else
return Qnil;
#endif
}
Gibt Informationen über die Gruppe mit der angegebenen Ganzzahl group_id zurück, wie sie in /etc/group gefunden wurden.
Die Informationen werden als Group-Struktur zurückgegeben.
Weitere Details finden Sie im Unix-Handbuch für getgrgid(3).
Beispiel
Etc.getgrgid(100) #=> #<struct Etc::Group name="users", passwd="x", gid=100, mem=["meta", "root"]>
Source
static VALUE
etc_getgrnam(VALUE obj, VALUE nam)
{
#ifdef HAVE_GETGRENT
struct group *grp;
const char *p = StringValueCStr(nam);
grp = getgrnam(p);
if (grp == 0) rb_raise(rb_eArgError, "can't find group for %"PRIsVALUE, nam);
return setup_group(grp);
#else
return Qnil;
#endif
}
Gibt Informationen über die Gruppe mit dem angegebenen name zurück, wie sie in /etc/group gefunden wurden.
Die Informationen werden als Group-Struktur zurückgegeben.
Weitere Details finden Sie im Unix-Handbuch für getgrnam(3).
Beispiel
Etc.getgrnam('users') #=> #<struct Etc::Group name="users", passwd="x", gid=100, mem=["meta", "root"]>
Source
static VALUE
etc_getlogin(VALUE obj)
{
char *login;
#ifdef HAVE_GETLOGIN
login = getlogin();
if (!login) login = getenv("USER");
#else
login = getenv("USER");
#endif
if (login) {
#ifdef _WIN32
rb_encoding *extenc = rb_utf8_encoding();
#else
rb_encoding *extenc = rb_locale_encoding();
#endif
return rb_external_str_new_with_enc(login, strlen(login), extenc);
}
return Qnil;
}
Gibt den kurzen Benutzernamen des aktuell angemeldeten Benutzers zurück. Leider ist es oft ziemlich einfach, ::getlogin zu täuschen.
Vermeiden Sie ::getlogin für sicherheitsrelevante Zwecke.
Wenn ::getlogin fehlschlägt, versuchen Sie ::getpwuid.
Weitere Details finden Sie im Unix-Handbuch für getpwuid(3).
z.B.
Etc.getlogin -> 'guest'
Source
static VALUE
etc_getpwent(VALUE obj)
{
#ifdef HAVE_GETPWENT
struct passwd *pw;
if ((pw = getpwent()) != 0) {
return setup_passwd(pw);
}
#endif
return Qnil;
}
Gibt einen Eintrag aus der Datei /etc/passwd zurück.
Beim ersten Aufruf wird die Datei geöffnet und der erste Eintrag zurückgegeben; jeder nachfolgende Aufruf gibt den nächsten Eintrag zurück oder nil, wenn das Ende der Datei erreicht ist.
Um die Datei nach Abschluss der Verarbeitung zu schließen, rufen Sie ::endpwent auf.
Jeder Eintrag wird als Passwd-Struktur zurückgegeben.
Source
static VALUE
etc_getpwnam(VALUE obj, VALUE nam)
{
#ifdef HAVE_GETPWENT
struct passwd *pwd;
const char *p = StringValueCStr(nam);
pwd = getpwnam(p);
if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %"PRIsVALUE, nam);
return setup_passwd(pwd);
#else
return Qnil;
#endif
}
Gibt die /etc/passwd-Informationen für den Benutzer mit dem angegebenen Login-name zurück.
Die Informationen werden als Passwd-Struktur zurückgegeben.
Weitere Details finden Sie im Unix-Handbuch für getpwnam(3).
Beispiel
Etc.getpwnam('root') #=> #<struct Etc::Passwd name="root", passwd="x", uid=0, gid=0, gecos="root",dir="/root", shell="/bin/bash">
Source
static VALUE
etc_getpwuid(int argc, VALUE *argv, VALUE obj)
{
#if defined(HAVE_GETPWENT)
VALUE id;
rb_uid_t uid;
struct passwd *pwd;
if (rb_scan_args(argc, argv, "01", &id) == 1) {
uid = NUM2UIDT(id);
}
else {
uid = getuid();
}
pwd = getpwuid(uid);
if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %d", (int)uid);
return setup_passwd(pwd);
#else
return Qnil;
#endif
}
Gibt die /etc/passwd-Informationen für den Benutzer mit der angegebenen Ganzzahl uid zurück.
Die Informationen werden als Passwd-Struktur zurückgegeben.
Wenn uid weggelassen wird, wird stattdessen der Wert von Passwd[:uid] zurückgegeben.
Weitere Details finden Sie im Unix-Handbuch für getpwuid(3).
Beispiel
Etc.getpwuid(0) #=> #<struct Etc::Passwd name="root", passwd="x", uid=0, gid=0, gecos="root",dir="/root", shell="/bin/bash">
Source
static VALUE
etc_group(VALUE obj)
{
#ifdef HAVE_GETGRENT
struct group *grp;
if (rb_block_given_p()) {
each_group();
}
else if ((grp = getgrent()) != 0) {
return setup_group(grp);
}
#endif
return Qnil;
}
Bietet einen praktischen Ruby-Iterator, der für jeden Eintrag in der Datei /etc/group einen Block ausführt.
Der Codeblock erhält eine Group-Struktur übergeben.
Siehe ::getgrent oben für Details.
Beispiel
require 'etc' Etc.group {|g| puts g.name + ": " + g.mem.join(', ') }
Source
static VALUE
etc_nprocessors(VALUE obj)
{
long ret;
#if !defined(_WIN32)
#if defined(HAVE_SCHED_GETAFFINITY) && defined(CPU_ALLOC)
int ncpus;
ncpus = etc_nprocessors_affin();
if (ncpus != -1) {
return INT2NUM(ncpus);
}
/* fallback to _SC_NPROCESSORS_ONLN */
#endif
errno = 0;
ret = sysconf(_SC_NPROCESSORS_ONLN);
if (ret == -1) {
rb_sys_fail("sysconf(_SC_NPROCESSORS_ONLN)");
}
#else
SYSTEM_INFO si;
GetSystemInfo(&si);
ret = (long)si.dwNumberOfProcessors;
#endif
return LONG2NUM(ret);
}
Gibt die Anzahl der aktiven Prozessoren zurück.
Das Ergebnis ist als Anzahl von Prozessen gedacht, die alle verfügbaren Prozessoren nutzen.
Diese Methode wird implementiert mit
-
sched_getaffinity(): Linux
-
sysconf(_SC_NPROCESSORS_ONLN): GNU/Linux, NetBSD, FreeBSD, OpenBSD, DragonFly BSD, OpenIndiana, Mac OS X, AIX
Beispiel
require 'etc' p Etc.nprocessors #=> 4
Das Ergebnis kann kleiner sein als die Anzahl der physischen CPUs, insbesondere wenn der Ruby-Prozess an bestimmte CPUs gebunden ist. Dies dient dazu, eine bessere parallele Verarbeitung zu erzielen.
Beispiel: (Linux)
linux$ taskset 0x3 ./ruby -retc -e "p Etc.nprocessors" #=> 2
Source
static VALUE
etc_passwd(VALUE obj)
{
#ifdef HAVE_GETPWENT
struct passwd *pw;
if (rb_block_given_p()) {
each_passwd();
}
else if ((pw = getpwent()) != 0) {
return setup_passwd(pw);
}
#endif
return Qnil;
}
Bietet einen praktischen Ruby-Iterator, der für jeden Eintrag in der Datei /etc/passwd einen Block ausführt.
Der Codeblock erhält eine Passwd-Struktur übergeben.
Siehe ::getpwent oben für Details.
Beispiel
require 'etc' Etc.passwd {|u| puts u.name + " = " + u.gecos }
Source
static VALUE
etc_setgrent(VALUE obj)
{
#ifdef HAVE_GETGRENT
setgrent();
#endif
return Qnil;
}
Setzt den Leseprozess der Datei /etc/group zurück, sodass der nächste Aufruf von ::getgrent erneut den ersten Eintrag zurückgibt.
Source
static VALUE
etc_setpwent(VALUE obj)
{
#ifdef HAVE_GETPWENT
setpwent();
#endif
return Qnil;
}
Setzt den Leseprozess der Datei /etc/passwd zurück, sodass der nächste Aufruf von ::getpwent erneut den ersten Eintrag zurückgibt.
Source
static VALUE
etc_sysconf(VALUE obj, VALUE arg)
{
int name;
long ret;
name = NUM2INT(arg);
errno = 0;
ret = sysconf(name);
if (ret == -1) {
if (errno == 0) /* no limit */
return Qnil;
rb_sys_fail("sysconf");
}
return LONG2NUM(ret);
}
Gibt eine Systemkonfigurationsvariable mithilfe von sysconf() zurück.
name sollte eine Konstante unter Etc sein, die mit SC_ beginnt.
Der Rückgabewert ist eine Ganzzahl oder nil. nil bedeutet unbegrenztes Limit. (sysconf() gibt -1 zurück, aber errno wird nicht gesetzt.)
Etc.sysconf(Etc::SC_ARG_MAX) #=> 2097152 Etc.sysconf(Etc::SC_LOGIN_NAME_MAX) #=> 256
Source
static VALUE
etc_sysconfdir(VALUE obj)
{
#ifdef _WIN32
return rb_w32_special_folder(CSIDL_COMMON_APPDATA);
#elif defined(LOAD_RELATIVE)
return rb_hash_aref(rbconfig(), rb_str_new_lit("sysconfdir"));
#else
return rb_filesystem_str_new_cstr(SYSCONFDIR);
#endif
}
Gibt das Systemkonfigurationsverzeichnis zurück.
Dies ist normalerweise "/etc", wird aber durch das Präfix modifiziert, das bei der Kompilierung von Ruby verwendet wurde. Wenn Ruby beispielsweise in /usr/local kompiliert und installiert wird, gibt es auf anderen Plattformen als Windows "/usr/local/etc" zurück.
Unter Windows gibt dies immer das vom System bereitgestellte Verzeichnis zurück.
Source
static VALUE
etc_systmpdir(VALUE _)
{
VALUE tmpdir;
#ifdef _WIN32
WCHAR path[_MAX_PATH];
UINT len = rb_w32_system_tmpdir(path, numberof(path));
if (!len) return Qnil;
tmpdir = rb_w32_conv_from_wchar(path, rb_filesystem_encoding());
#else
const char default_tmp[] = "/tmp";
const char *tmpstr = default_tmp;
size_t tmplen = strlen(default_tmp);
# if defined _CS_DARWIN_USER_TEMP_DIR
#ifndef MAXPATHLEN
#define MAXPATHLEN 1024
#endif
char path[MAXPATHLEN];
size_t len;
len = confstr(_CS_DARWIN_USER_TEMP_DIR, path, sizeof(path));
if (len > 0) {
tmpstr = path;
tmplen = len - 1;
if (len > sizeof(path)) tmpstr = 0;
}
# endif
tmpdir = rb_filesystem_str_new(tmpstr, tmplen);
# if defined _CS_DARWIN_USER_TEMP_DIR
if (!tmpstr) {
confstr(_CS_DARWIN_USER_TEMP_DIR, RSTRING_PTR(tmpdir), len);
}
# endif
#endif
#ifndef RB_PASS_KEYWORDS
/* untaint on Ruby < 2.7 */
FL_UNSET(tmpdir, FL_TAINT);
#endif
return tmpdir;
}
Gibt das temporäre Verzeichnis des Systems zurück; normalerweise „/tmp“.
Source
static VALUE
etc_uname(VALUE obj)
{
#ifdef _WIN32
OSVERSIONINFOW v;
SYSTEM_INFO s;
const char *sysname, *mach;
VALUE result, release, version;
VALUE vbuf, nodename = Qnil;
DWORD len = 0;
WCHAR *buf;
v.dwOSVersionInfoSize = sizeof(v);
if (!GetVersionExW(&v))
rb_sys_fail("GetVersionEx");
result = rb_hash_new();
switch (v.dwPlatformId) {
case VER_PLATFORM_WIN32s:
sysname = "Win32s";
break;
case VER_PLATFORM_WIN32_NT:
sysname = "Windows_NT";
break;
case VER_PLATFORM_WIN32_WINDOWS:
default:
sysname = "Windows";
break;
}
rb_hash_aset(result, SYMBOL_LIT("sysname"), rb_str_new_cstr(sysname));
release = rb_sprintf("%lu.%lu.%lu", v.dwMajorVersion, v.dwMinorVersion, v.dwBuildNumber);
rb_hash_aset(result, SYMBOL_LIT("release"), release);
version = rb_sprintf("%s Version %"PRIsVALUE": %"PRIsVALUE, sysname, release,
rb_w32_conv_from_wchar(v.szCSDVersion, rb_utf8_encoding()));
rb_hash_aset(result, SYMBOL_LIT("version"), version);
# define GET_COMPUTER_NAME(ptr, plen) GetComputerNameExW(ComputerNameDnsFullyQualified, ptr, plen)
GET_COMPUTER_NAME(NULL, &len);
buf = ALLOCV_N(WCHAR, vbuf, len);
if (GET_COMPUTER_NAME(buf, &len)) {
nodename = rb_w32_conv_from_wchar(buf, rb_utf8_encoding());
}
ALLOCV_END(vbuf);
if (NIL_P(nodename)) nodename = rb_str_new(0, 0);
rb_hash_aset(result, SYMBOL_LIT("nodename"), nodename);
# ifndef PROCESSOR_ARCHITECTURE_AMD64
# define PROCESSOR_ARCHITECTURE_AMD64 9
# endif
# ifndef PROCESSOR_ARCHITECTURE_INTEL
# define PROCESSOR_ARCHITECTURE_INTEL 0
# endif
GetSystemInfo(&s);
switch (s.wProcessorArchitecture) {
case PROCESSOR_ARCHITECTURE_AMD64:
mach = "x64";
break;
case PROCESSOR_ARCHITECTURE_ARM:
mach = "ARM";
break;
case PROCESSOR_ARCHITECTURE_INTEL:
mach = "x86";
break;
default:
mach = "unknown";
break;
}
rb_hash_aset(result, SYMBOL_LIT("machine"), rb_str_new_cstr(mach));
#else
struct utsname u;
int ret;
VALUE result;
ret = uname(&u);
if (ret == -1)
rb_sys_fail("uname");
result = rb_hash_new();
rb_hash_aset(result, SYMBOL_LIT("sysname"), rb_str_new_cstr(u.sysname));
rb_hash_aset(result, SYMBOL_LIT("nodename"), rb_str_new_cstr(u.nodename));
rb_hash_aset(result, SYMBOL_LIT("release"), rb_str_new_cstr(u.release));
rb_hash_aset(result, SYMBOL_LIT("version"), rb_str_new_cstr(u.version));
rb_hash_aset(result, SYMBOL_LIT("machine"), rb_str_new_cstr(u.machine));
#endif
return result;
}
Gibt die Systeminformationen zurück, die durch den uname-Systemaufruf erhalten wurden.
Der Rückgabewert ist ein Hash, der mindestens 5 Schlüssel hat
:sysname, :nodename, :release, :version, :machine
Beispiel
require 'etc' require 'pp' pp Etc.uname #=> {:sysname=>"Linux", # :nodename=>"boron", # :release=>"2.6.18-6-xen-686", # :version=>"#1 SMP Thu Nov 5 19:54:42 UTC 2009", # :machine=>"i686"}