Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Работа со строками Bash

Дорогие форумчане, возникла резкая необходимость. В этих делах не в зуб ногой.
Файл с содержимым показывает вызов функции mail() в определённом файле:

user1 (mail) (dsbsmo4@list.ru) /home/user1/data/www/wp-config/erwkcwkcw.php
user3 (mail) (jfen835@list.ru) /home/user3/data/www/admin/system/cxmxmc.php
user3 (site) /home/user3/data/www/site.ru/index.php
user2 (mail) (hrj34fucr@list.ru) /home/user2/data/www/fake/root.php
user1 (mail) (r834fnjv@list.ru) /home/user1/data/www/wp-config/erwkcwkcw.php
user2 (site) /home/user1/data/www/order.ru/index.php
user2 (mail) (segkfwmkf@list.ru) /home/user1/data/www/sfmve/dskjfs/.404.php
user2 (mail) (dsfsdsd@list.ru) /home/user1/data/www/fdgkgd/43fmke.php
user2 (site) /home/user1/data/www/fiction/index.php
user1 (mail) (ewriwr43n@list.ru) /home/user1/data/www/site/assets/owl.php
user1 (mail) (sdmn348934@list.ru) /home/user1/data/www/mail/postform.php
user1 (mail) (pweneife@list.ru) /home/user1/data/www/wp-config/erwkcwkcw.php
Посчитать количество раз вызова функции mail() в файле для всех пользователей.

Вывести только:
count USER PATH
(взять за «ключ» «USER PATH»)

Например:
3 user1 /home/user1/data/www/wp-config/erwkcwkcw.php
Ответ:
Bash
1
awk '$2 ~ /mail/ {t[$1" "$4]++}; END { for (var in t) print t[var], var}' text
Вопрос: Подскажите, как правильно сделать (bash, echo, pipes)

Приветствую!

Я не очень опытный пользователь Linux, поэтому сорри за возможно ламерский вопрос.
У меня задача: в CentOS7 строкой в файле bash (или в командной строке) сделать следующее: в определенный файл (допустим /tmp/my.txt) записать некую константную строку (допустим, "My PC hostname is"), затем добавить пробел и в той же строке вывести текущее имя хоста, получаемое выполнением команды hostname.

Что то типа такого (но так не работает - выводит только строку с именем хоста, без предшествующей константной части, это я привел для иллюстрации того, как я пытаюсь сделать):

 echo $'My PC hostname is ' | hostname >> /tmp/my.txt 


P.S. подсветки кода sh/bash на форуме, как я понял, нет, так что извините за некорретную подсветку

Спасибо.
Ответ:
Los Pejos
Приветствую!

Я не очень опытный пользователь Linux, поэтому сорри за возможно ламерский вопрос.
У меня задача: в CentOS7 строкой в файле bash (или в командной строке) сделать следующее: в определенный файл (допустим /tmp/my.txt) записать некую константную строку (допустим, "My PC hostname is"), затем добавить пробел и в той же строке вывести текущее имя хоста, получаемое выполнением команды hostname.

Что то типа такого (но так не работает - выводит только строку с именем хоста, без предшествующей константной части, это я привел для иллюстрации того, как я пытаюсь сделать):

 echo $'My PC hostname is ' | hostname >> /tmp/my.txt 


P.S. подсветки кода sh/bash на форуме, как я понял, нет, так что извините за некорретную подсветку

Спасибо.

Вы не поняли, что значит | (пайп). погуглите на тему.
Вопрос: Вывод определенных строк

Добрый день.

Есть задача: средствами командной строки (лучше) или скриптом (хуже) выводить определенный промежуток строк.
Поясняя:

Определенный скрипт выводит на экран информацию в таком формате:
Bash
1
2
3
4
5
6
7
8
CPU:             Core1: ....
                 Core2: ....
                 .........
RAM:             Device-1:.......
                 Device-2:.......
.....
.....
.....            CPU ......
Есть необходимость не модифицируя сам скрипт, получать только нужную нам информацию, к примеру о CPU.
Каким образом можно было бы это организовать?
Ответ:
Bash
1
.....   | sed '/RAM:/{:a;n;/^\s/ba};d'
Вопрос: Bash скрипт для скачивания картинок с веб-сайта

Нашел замечательный скрипт с данного источника -

#!/bin/bash
#Description: Images downloader
#Filename: img_downloader.sh
if [ $# -ne 3 ];
then
echo "Usage: $0 URL -d DIRECTORY"
exit -1
fi
for i in {1..4}
do
case $1 in
-d) shift; directory=$1; shift ;;
*) url=${url:-$1}; shift;;
esac
done
mkdir -p $directory;
baseurl=$(echo $url | egrep -o "https?://[a-z.]+")
curl –s $url | egrep -o "<img src=[^>]*>" | sed 's/<img src=\"\([^"]*\).*/\1/g' > /tmp/$$.list
sed -i "s|^/|$baseurl/|" /tmp/$$.list
cd $directory;
while read filename;
do
curl –s -O "$filename" --silent
done < /tmp/$$.list


Но к сожалению при выполнение команды под root пользователем, выдает Permission Denied. Подскажите в чем может быть проблема.
sh-3.2# ./img_downloader.sh http://www.flickr.com/search/?q=linux -d images
sh: ./img_downloader.sh: Permission denied
sh-3.2# whoami
root
sh-3.2# 
Ответ: брад галимый. я скачивал коллекцию картинок на вноый товар с сайта одной строкой по типу xsel | wget -O - | sed | wget

ну иногда небольшие вариации, например если надо переименовал файл..

xsel -b|wget -i - -O -|sed -rn 's/^.*"(http[^"]+.(gif|jpg|jpeg)).*/\1/p' |sed 's/thumb/full/' | wget -ci -


что-то по типу этого. но там не было двух картинок (нужных мне) указанных в одной строке исходников. (и второй сед явно не обязателен :) )
Вопрос: Помогите с bash новичку

Новичок в bash'е

есть папка OPTION_FL
-- подпапки
--- BATO
--- MCRY
--- XCBO

В каждой подпапке много zip архивов.

Как пробежаться по каждой подпапке и по каждому zip архиву внутри подпапки разархировать все zip и сложить в один файл ?
Ответ:
x17.mstu
x17.mstu,

find -type f -iname '*.gz' -execdir bash -c 'mkdir -p photo ; gunzip -d photo {}' \;


Попробовал вот так но папка photo не создается, это папка куда хочу положить все разипаные файлы

а сперва создать папку, а потом уже разархивировать туда?
Вопрос: Парсинг вывода команды на bash

Здравствуйте, есть результат выполнения утилиты:
Код Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
sh-4.1# failover info
Running failover info
Versions: ViPNet 3.3.0 (921), daemon 1.5 (1)
Workstation configured for ID *(*)
The workstation works in a cluster mode of protection against failures
Workstation time (utc: 1429845555) Fri Apr 24 09:19:15 2015
 
                * local         * remote
failover mode   * active        * passive
failover uptime * 0d 15:11      * 0d 15:09
total cpu       * 29%           * 30%
total memory    * 2047532 kB    * 2047532 kB
free memory     * 1748088 kB    * 1844296 kB
failover state  * works         * works
failover cpu    * 3%            * 2%
iplir state     * works         * works
iplir cpu       * 13%           * 0%
mftp state      * works         * works
mftp cpu        * 25%           * 33%
Нужен скрипт на баше (или, может быть, это возможно сделать одной командой), который при передаче ему параметра, например, iplir cpu, выдавал только числовое значение из столбца "* local". Параметры которые будут передаваться скрипту, имеют только числовые значения, а именно: failover cpu, iplir cpu, mftp cpu.

В общем, результат должен выглядеть так:
Код Bash
1
2
#./script.sh failover cpu
3
А еще, как вариант, мне подойдёт утилита, возвращающая загруженность процессора определенным процессом в момент обращения (ps не подойдёт).

Надеюсь на вашу помощь.
Ответ: Была бы охота вводить такие длинные строки, ксли достаточно 1 первой буквы
Код Bash
1
2
3
4
5
6
7
8
9
#!/bin/bash
case $1 in 
    f*) p='failover' ;;
    i*) p='iplir' ;;
    m*) p='mftp' ;;
    *) echo "Wrong input. Use f/i/m symbols for failover/iplir/mftp cpu data" ; exit 1 ;;
esac
 
failover info | grep -oP "$p cpu\s*\*\s*\K[0-9]*"
Вопрос: Помогите не передаются входные программы из Autosys в bash script

bash-4.1$ /home/kushnira/archive_infile.bash $${FILE_DIR} $${ARCH_DIR} OPTION TL

сам скрипт archive_infile.bash:

#!/bin/bash

echo "Starting..."

INDIR=$1;
ARCH_DIR=$2;
ASSET_CLASS=$3;
ASSET_LEVEL=$4;
TIMESTAMP=$(date +%Y%m%d%H%M%S);

zip -r $ARCH_DIR$ASSET_CLASS\_$ASSET_LEVEL\_$TIMESTAMP.zip $INDIR;

входный параметр $${FILE_DIR}=/home/kushnira/FILE_DIR
$${ARCH_DIR}=/home/kushnira/$INDIR

При запуске получаю ошибку
Starting...
zip warning: name not matched: 2064455{FILE_DIR}

zip error: Nothing to do! (try: zip -r 2064455{ARCH_DIR}OPTION_TL_20180710142227.zip . -i 2064455{FILE_DIR})
bash-4.1$
Ответ:
x17.mstu
bash-4.1$ /home/kushnira/archive_infile.bash $${FILE_DIR} $${ARCH_DIR} OPTION TL


сам скрипт archive_infile.bash:

#!/bin/bash

echo "Starting..."

INDIR=$1;
ARCH_DIR=$2;
ASSET_CLASS=$3;
ASSET_LEVEL=$4;
TIMESTAMP=$(date +%Y%m%d%H%M%S);

zip -r $ARCH_DIR$ASSET_CLASS\_$ASSET_LEVEL\_$TIMESTAMP.zip $INDIR;

входный параметр $${FILE_DIR}=/home/kushnira/FILE_DIR
$${ARCH_DIR}=/home/kushnira/$INDIR

При запуске получаю ошибку
Starting...
        zip warning: name not matched: 2064455{FILE_DIR}

zip error: Nothing to do! (try: zip -r 2064455{ARCH_DIR}OPTION_TL_20180710142227.zip . -i 2064455{FILE_DIR})
bash-4.1$


Мессир, вы неправильно готовите

Ваш Вызов превращается в тыкву следущее (мои комментарии):

 
## Абсолютное имя выполняемого файла (правильно)
/home/kushnira/archive_infile.bash 

## pid текущего процесса, превращается в текущий Pid 2064455
$$ 

## та строка которую вы видите вместо части имени файла
{FILE_DIR} 

## pid текущего процесса, превращается в текущий Pid 2064455
$$
{ARCH_DIR} 
## остаток строки
OPTION TL


Попробуйте:
bash-4.1$ /home/kushnira/archive_infile.bash ${FILE_DIR} ${ARCH_DIR} OPTION TL


Где
${FILE_DIR} - значение переменной окружения FILE_DIR (Она у Вас определена?)
${ARCH_DIR} - значение переменной окружения ARCH_DIR (Она у Вас определена?)

проверить можно:
env | grep FILE_DIR
env | grep ARCH_DIR

если не определено, пропишите явно
проверьте что эти директории существуют
Вопрос: Программа записи в файл bash

Разработать программу записи в файл из вводимой с клавиатуры последовательности чисел,
лишь тех, которые входят в диапазон, заданный с клавиатуры.
Имя файла задаётся пользователем в командной строке.
Если оно не задано, создать файл в домашнем каталоге пользователя с названием Numbers.txt.
При наличии такого файла – дописывать в него данные с новой строки.
Надо написать на bash.
Сделал на С++, но проблемы с переводом на bash.
Код C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <fstream>
 using namespace std;
int main(int argc, char*argv[])
{
setlocale (0,"RUS");
    int a, b, c, i = 0;
    char outfile[BUFSIZ] = { 0 };
    ofstream ofile;
 
    cout << "Введите начало диапазона: ";
    cin >> a;
    cout << "Введите конец диапазона: ";
    cin >> b;
    if (a > b) cout << "Неверный ввод (a > b)!" << endl, exit(1);
 
    if (argc != 1) strcpy(outfile, argv[1]);
 
    if (!*outfile)
    {
        strcpy(outfile, "Numbers.txt");
    }
 
    ofile.open(outfile);
 
    do
    {
        cout << "Введите число: ";
        cin >> c;
 
        if (c <= b && c >= a) ofile << c << " ";
        i++;
    } while (i != 10);
    ofile.close();
    system ("pause");
    return 0;
}
Ответ: Пока значение а (которое поочередно принимает значения start end) не будет числом вызывается процедура из 2-х команд: вывод на экран сообщения "start( или end) should be a number" и приглашения "Range start( или end):" с сохранением ввода пользователя в переменную start( или end)
P.S. Вы думаете отступы просто так ставятся? Это для наглядности, где какой цикл начинается и заканчивается (а так я всё в 1 строчку могу написать)
Вопрос: Как вывести список процессов bash, запущенных определённым пользователем?

Здравствуйте!

Люди, не могли бы мне помочь?

Вот задание:
"Реализовать командный файл, который при старте выводит информацию о системе, информацию о пользователе, запустившем данный командный файл, далее в цикле выводит список активных пользователей в системе – запрашивает имя пользователя и выводит список всех процессов bash запущенных данным пользователем."

Меня интересует только выделенная часть текста.

1. "список активных пользователей в системе" - здесь я записал команду who, но не уверен ее в правильности. Т.к. в литературе встречались разные описания: то список зарегистрированных пользователей, то список активных пользователей. Уточните мне, пожалуйста.



2. "список всех процессов bash запущенных данным пользователем" - здесь я вовсе не знаю какую команду писать. Есть предположение что ps, но я не нашел в справочниках как выдать только bash-процессы. Так как выдать этот список?
Ответ: Как будет выглядеть данное задание?
Написать командный файл подсчитывающий количество определенных процессов пользователя (Ввести имя пользователя и название процесса)
Вопрос: Вывод bash скрипта в формате JSON

Добрый день!
Обращаюсь за помощью к специалистам.

Задача - сделать отображение состояния бекапов встроенными средствами виртуальной платформы Proxmox через Zabbix.
Ничего готового не нашел. Зато нашел опубликованный пользователем skygge на форуме zabbix.com скрипт: . Скрипт очень хороший, но очень малоинформативный.
После исследования и раздумий принял решение попробовать своими силами и минимальным знанием скриптинга его переделать полноценный шаблон с автоматическим обнаружением виртуалок, и мониторинга состояния бекапа каждой. Если получится, то опубликую на share.zabbix.com.

Проблема: как и ожидал, застрял на выводе результатов в формате JSON, которые нужно передавать в Zabbix.
Вот мой discovery-script на текущем этапе:

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/bin/bash
 
# Script for checking ProxMox virtual machines backup. For use in Zabbix. Skygge@2016
 
#Variables
 
backupconfig='/etc/pve/vzdump.cron'
storageconfig='/etc/pve/storage.cfg'
configdir='/etc/pve/local/qemu-server'
 
# Virtual machines
virtualmachines=`find $configdir -type f -name "*.conf" |cut -d "/" -f 6|cut -d "." -f 1`
 
# Backup Configuration for VM's
backupallmachines=`grep '\-\-all' $backupconfig|wc -l`
 
# Check every VM for configured backup
if [ "$backupallmachines" = "0" ]; then
for i in $virtualmachines
do
    backupenabled=1
 
    checkbackup=`grep $i $backupconfig |sed 's/  */ /g'|cut -d "-" -f 1|cut -d " " -f 8-|tr -d "\n"`
    if [ "$checkbackup" = "" ];then
        echo "VM $i is not configured for backups."
        backupenabled=0
    fi
 
    checkbackupenabled=`grep $i $backupconfig | grep "#vzdump" | sed 's/  */ /g'|cut -d "-" -f 1|cut -d " " -f 8-|tr -d "\n"`
    if ! [ "$checkbackupenabled" = "" ];then
        echo "Backup for VM $i is configured, but disabled."
        backupenabled=0
    fi
 
 
echo -e "{\"VM_NUMBER\":\""$i"\", \"BACKUP_STATUS\":\""$i,$backupenabled"\"}"
 
done
fi
(Выводы "echo" оставил пока что сознательно, для траблшутинга. Знаю, что в выводе лишнего быть не должно.)


Вывод сейчас такой:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# ./vms_discovery
{"VM_NUMBER":"100", "BACKUP_STATUS":"100,1"}
 
$ sudo ./vms_discovery
{"VM_NUMBER":"106", "BACKUP_STATUS":"106,1"}
{"VM_NUMBER":"103", "BACKUP_STATUS":"103,1"}
{"VM_NUMBER":"101", "BACKUP_STATUS":"101,1"}
 
$ sudo ./vms_discovery
VM 106 is not configured for backups.
{"VM_NUMBER":"106", "BACKUP_STATUS":"106,0"}
{"VM_NUMBER":"103", "BACKUP_STATUS":"103,1"}
VM 101 is not configured for backups.
{"VM_NUMBER":"101", "BACKUP_STATUS":"101,0"}
Вот из этого всего прошу, пожалуйста, помочь мне сделать полноценный JSON. Самое страшное для меня - запятые после блоков данных, которые надо расставить не просто тупо в конце каждой строки, а пропустить последнюю. Вот тут я в лужу сел полностью.

Вот пример вывода, который Zabbix принимает на ура:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
{
        "data":[
 
                {
                        "{#DISKNAME}":"/dev/sda -d sat",
                        "{#DISK_STATUS}":"1,1"
                },
                {
                        "{#DISKNAME}":"/dev/sdb -d sat",
                        "{#DISK_STATUS}":"1,1"
                }
        ]
}
(взято из другого скрипта)

Самое интересное, что тут есть даже готовое решение: , и им можно было бы попробовать воспользоваться. Вот только прикрутить его у меня ума на текущем жизненном этапе не хватает.

Заранее благодарен за помощь!
Ответ: Max Dark,

Не по теме:

ну что и требовалось доказать: вместо скрипта на 20 строк из которых значимых команд: grep, find и цикл получаем одороболо на почти 100 строк...