Я бы использовал для этого awk
вместо cut
, например:
#!/bin/bash
echo "Press 1 for user name, 2 for terminal name, 3 for login date and 4 for time"
read ch
case $ch in
1)
who | awk '{ print $1 }'
;;
2)
who | awk '{ print $2 }'
;;
3)
who | awk '{ print $3 " " $4 }'
;;
4)
who | awk '{ print $5 }'
;;
*)
echo "Wrong input"
esac
Примеры выполнения:
./whoList.sh
Press 1 for user name, 2 for terminal name, 3 for login date and 4 for time
2
console
ttys000
ttys001
./whoList.sh
Press 1 for user name, 2 for terminal name, 3 for login date and 4 for time
3
Oct 3
Oct 3
Oct 3
./whoList.sh
Press 1 for user name, 2 for terminal name, 3 for login date and 4 for time
1
maulinglawns
maulinglawns
maulinglawns
./whoList.sh
Press 1 for user name, 2 for terminal name, 3 for login date and 4 for time
4
09:01
09:44
11:01
./whoList.sh
Press 1 for user name, 2 for terminal name, 3 for login date and 4 for time
7
Wrong input
Вывод, как вы можете видеть, находится в одной колонке, а не на одной строке.
Редактировать:
Проверено под OS X 10.11.6
bash --version
GNU bash, версия 3.2.57(1)-release (x86_64-apple-darwin15)
Используйте параметр -n
, чтобы проверить, есть ли у вас все еще права; из man sudo
:
-n , - неинтерактивный
Избегайте запроса пользователя на ввод любого вида. Если для запуска команды требуется пароль, sudo отобразит сообщение об ошибке и завершится.
Например,
sudo -n true 2>/dev/null && echo Privileges active || echo Privileges inactive
Имейте в виду, что привилегии могут истечь между проверкой с помощью sudo -n true
и их фактическим использованием. Вы можете попробовать напрямую с помощью sudo -n command ...
и в случае неудачи отобразить сообщение и, возможно, повторить интерактивный запуск sudo
.
Edit: См. Также комментарий ruakh ниже.
Выполнить:
sudo -nv
Если ваши привилегии sudo истекли, произойдет выход с кодом выхода 1 и выводом:
sudo: a password is required
Если у вас есть действительный кэшированные учетные данные, эта команда завершится успешно и ничего не выведет.
Итак, чтобы собрать все вместе, вот скриптлет, который молча проверяет, есть ли у вас действительные кэшированные учетные данные:
if sudo -nv 2>/dev/null; then
echo "no sudo password required"
else
echo "sudo password expired"
fi
Как упоминалось в других ответах / комментариях, -v
опция ("проверка") для sudo автоматически обновляет кэшированные учетные данные, если есть какие-либо или еще запросы на аутентификацию для генерации кэшированных учетных данных, а параметр -n
("неинтерактивный") предотвращает создание sudo любые интерактивные запросы, такие как запрос аутентификации.
sudo -nv
работает нормально, но загрязняет системные журналы ошибками sudo и информацией аутентификации pam . Мне нужно было проверить привилегии sudo для моего приглашения bash, поэтому оно выполнялось довольно часто, и мои журналы состояли почти только из этого шума.
Можно напрямую проанализировать файл временной метки sudo - я написал для него небольшую утилиту на C:
/* compile and set permissions: */
/* $ gcc checksudo.c -o checksudo -std=gnu99 -O2 */
/* $ chown root:root checksudo */
/* $ chmod +s checksudo */
#define USERNAME "replace-with-your-username"
#define TIMEOUT 5
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <time.h>
void timespec_diff(struct timespec *start, struct timespec *stop, struct timespec *result) {
if ((stop->tv_nsec - start->tv_nsec) < 0) {
result->tv_sec = stop->tv_sec - start->tv_sec - 1;
result->tv_nsec = stop->tv_nsec - start->tv_nsec + 1000000000;
} else {
result->tv_sec = stop->tv_sec - start->tv_sec;
result->tv_nsec = stop->tv_nsec - start->tv_nsec;
}
return;
}
int main(int argc, char** argv) {
if (geteuid() != 0) {
printf("uid is not 0 - checksudo must be owned by uid 0 and have the setuid bit set\n");
return 2;
}
struct timespec current_time;
if (clock_gettime(CLOCK_BOOTTIME, ¤t_time) != 0) {
printf("Unable to get current time: %s\n", strerror(errno));
return 2;
}
struct stat ttypath_stat;
if (stat(ttyname(0), &ttypath_stat) != 0) {
printf("Unable to stat current tty: %s\n", strerror(errno));
return 2;
}
FILE* timestamp_fd = fopen("/var/run/sudo/ts/" USERNAME, "rb");
if (timestamp_fd == NULL) {
printf("Unable to open sudo timestamp file: %s\n", strerror(errno));
return 2;
}
long offset = 0;
int found = 0;
while (1) {
if (fseek(timestamp_fd, offset, SEEK_SET) != 0) {
printf("Failed to seek timestamp file: %s\n", strerror(errno));
return 2;
}
unsigned short timestamp_entry_header[4];
if (feof(timestamp_fd)) {
printf("matching timestamp not found\n");
return 2;
}
if (fread(×tamp_entry_header, sizeof(unsigned short), 4, timestamp_fd) < 4) {
break;
}
if (ferror(timestamp_fd)) {
printf("IO error when reading timestamp file\n");
return 2;
}
// read tty device id
if (timestamp_entry_header[2] == 2 && timestamp_entry_header[3] == 0) {
if (fseek(timestamp_fd, offset + 32, SEEK_SET) != 0) {
printf("Failed to seek timestamp file: %s\n", strerror(errno));
return 2;
}
dev_t tty_dev_id;
if (fread(&tty_dev_id, sizeof(dev_t), 1, timestamp_fd) < 1) {
printf("EOF when reading tty device id\n");
return 2;
}
if (tty_dev_id == ttypath_stat.st_rdev) {
// read timestamp
if (fseek(timestamp_fd, offset + 16, SEEK_SET) != 0) {
printf("Failed to seek timestamp file: %s\n", strerror(errno));
return 2;
}
struct timespec sudo_time;
if (fread(&sudo_time, sizeof(struct timespec), 1, timestamp_fd) < 1) {
printf("EOF when reading timestamp\n");
return 2;
}
struct timespec time_since_sudo;
timespec_diff(&sudo_time, ¤t_time, &time_since_sudo);
found = time_since_sudo.tv_sec < TIMEOUT * 60;
break;
}
}
offset += timestamp_entry_header[1];
}
fclose(timestamp_fd);
return !found;
}