Como Executar Consultas MySQL a Partir da Linha de Comando do Linux
Se você é responsável por gerenciar um servidor de banco de dados, de vez em quando pode ser necessário executar uma consulta e inspecioná-la cuidadosamente. Embora você possa fazer isso a partir do shell do MySQL/MariaDB, esta dica permitirá que você execute as consultas do MySQL/MariaDB diretamente usando a linha de comando do Linux E salve a saída em um arquivo para inspeção posterior (isso é particularmente útil se a consulta retornar muitos registros).
Vamos olhar alguns exemplos simples de execução de consultas MYSQL diretamente da linha de comando antes de passarmos para uma consulta mais avançada.
Configurando Bancos de Dados de Exemplo
Antes de mergulharmos nos comandos, vamos configurar os bancos de dados de exemplo com os quais trabalharemos ao longo deste guia, para que você possa acompanhar e praticar essas técnicas em seu próprio sistema.
Criando o banco de dados tecmintdb
Primeiro, vamos criar o banco de dados tecmintdb e a tabela tutorials:
mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS tecmintdb;"
Em seguida, para criar uma tabela de banco de dados chamada tutorials no banco de dados tecmintdb, execute o comando abaixo:
sudo mysql -u root -p tecmintdb << 'EOF'
CREATE TABLE IF NOT EXISTS tutorials (
tut_id INT NOT NULL AUTO_INCREMENT,
tut_title VARCHAR(100) NOT NULL,
tut_author VARCHAR(40) NOT NULL,
submission_date DATE,
PRIMARY KEY (tut_id)
);
INSERT INTO tutorials (tut_title, tut_author, submission_date) VALUES
('Getting Started with Linux', 'John Smith', '2024-01-15'),
('Advanced Bash Scripting', 'Sarah Johnson', '2024-02-20'),
('MySQL Database Administration', 'Mike Williams', '2024-03-10'),
('Apache Web Server Configuration', 'Emily Brown', '2024-04-05'),
('Python for System Administrators', 'David Lee', '2024-05-12'),
('Docker Container Basics', 'Lisa Anderson', '2024-06-18'),
('Kubernetes Orchestration', 'Robert Taylor', '2024-07-22'),
('Linux Security Hardening', 'Jennifer Martinez', '2024-08-30');
EOF
Verifique se os dados foram inseridos:
sudo mysql -u root -p -e "USE tecmintdb; SELECT * FROM tutorials;"
Criando o banco de dados de funcionários
Agora, vamos criar um banco de dados employees mais complexo com várias tabelas relacionadas, este é o banco de dados que usaremos para os exemplos de consultas mais avançadas:
sudo mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS employees;"
Crie a tabela employees:
sudo mysql -u root -p employees << 'EOF'
CREATE TABLE IF NOT EXISTS employees (
emp_no INT NOT NULL AUTO_INCREMENT,
birth_date DATE NOT NULL,
first_name VARCHAR(14) NOT NULL,
last_name VARCHAR(16) NOT NULL,
gender ENUM('M','F') NOT NULL,
hire_date DATE NOT NULL,
PRIMARY KEY (emp_no)
);
INSERT INTO employees (emp_no, birth_date, first_name, last_name, gender, hire_date) VALUES
(10001, '1953-09-02', 'Georgi', 'Facello', 'M', '1984-06-02'),
(10002, '1964-06-02', 'Bezalel', 'Simmel', 'F', '1984-11-21'),
(10003, '1959-12-03', 'Parto', 'Bamford', 'M', '1984-08-28'),
(10004, '1954-05-01', 'Chirstian', 'Koblick', 'M', '1984-12-01'),
(10005, '1955-01-21', 'Kyoichi', 'Maliniak', 'M', '1984-09-15'),
(10006, '1953-04-20', 'Anneke', 'Preusig', 'F', '1985-02-18'),
(10007, '1957-05-23', 'Tzvetan', 'Zielinski', 'F', '1985-03-20'),
(10008, '1958-02-19', 'Saniya', 'Kalloufi', 'M', '1984-07-11'),
(10009, '1952-04-19', 'Sumant', 'Peac', 'F', '1985-02-18'),
(10010, '1963-06-01', 'Duangkaew', 'Piveteau', 'F', '1984-08-24');
EOF
Crie a tabela salaries:
sudo mysql -u root -p employees << 'EOF'
CREATE TABLE IF NOT EXISTS salaries (
emp_no INT NOT NULL,
salary INT NOT NULL,
from_date DATE NOT NULL,
to_date DATE NOT NULL,
PRIMARY KEY (emp_no, from_date),
FOREIGN KEY (emp_no) REFERENCES employees(emp_no) ON DELETE CASCADE
);
INSERT INTO salaries (emp_no, salary, from_date, to_date) VALUES
(10001, 60117, '1984-06-02', '1985-06-02'),
(10001, 62102, '1985-06-02', '1986-06-02'),
(10001, 66074, '1986-06-02', '9999-01-01'),
(10002, 65828, '1984-11-21', '1985-11-21'),
(10002, 65909, '1985-11-21', '9999-01-01'),
(10003, 40006, '1984-08-28', '1985-08-28'),
(10003, 43616, '1985-08-28', '9999-01-01'),
(10004, 40054, '1984-12-01', '1985-12-01'),
(10004, 42283, '1985-12-01', '9999-01-01'),
(10005, 78228, '1984-09-15', '1985-09-15'),
(10005, 82507, '1985-09-15', '9999-01-01'),
(10006, 40000, '1985-02-18', '1986-02-18'),
(10006, 43548, '1986-02-18', '9999-01-01'),
(10007, 56724, '1985-03-20', '1986-03-20'),
(10007, 60605, '1986-03-20', '9999-01-01'),
(10008, 46671, '1984-07-11', '1985-07-11'),
(10008, 48584, '1985-07-11', '9999-01-01'),
(10009, 60929, '1985-02-18', '1986-02-18'),
(10009, 64604, '1986-02-18', '9999-01-01'),
(10010, 72488, '1984-08-24', '1985-08-24'),
(10010, 74057, '1985-08-24', '9999-01-01');
EOF
Crie a tabela departments para junções mais complexas:
sudo mysql -u root -p employees << 'EOF'
CREATE TABLE IF NOT EXISTS departments (
dept_no CHAR(4) NOT NULL,
dept_name VARCHAR(40) NOT NULL,
PRIMARY KEY (dept_no),
UNIQUE KEY (dept_name)
);
INSERT INTO departments (dept_no, dept_name) VALUES
('d001', 'Marketing'),
('d002', 'Finance'),
('d003', 'Human Resources'),
('d004', 'Production'),
('d005', 'Development'),
('d006', 'Quality Management');
EOF
Crie a tabela dept_emp para vincular employees aos departments:
sudo mysql -u root -p employees << 'EOF'
CREATE TABLE IF NOT EXISTS dept_emp (
emp_no INT NOT NULL,
dept_no CHAR(4) NOT NULL,
from_date DATE NOT NULL,
to_date DATE NOT NULL,
PRIMARY KEY (emp_no, dept_no),
FOREIGN KEY (emp_no) REFERENCES employees(emp_no) ON DELETE CASCADE,
FOREIGN KEY (dept_no) REFERENCES departments(dept_no) ON DELETE CASCADE
);
INSERT INTO dept_emp (emp_no, dept_no, from_date, to_date) VALUES
(10001, 'd005', '1984-06-02', '9999-01-01'),
(10002, 'd005', '1984-11-21', '9999-01-01'),
(10003, 'd004', '1984-08-28', '9999-01-01'),
(10004, 'd004', '1984-12-01', '9999-01-01'),
(10005, 'd003', '1984-09-15', '9999-01-01'),
(10006, 'd005', '1985-02-18', '9999-01-01'),
(10007, 'd004', '1985-03-20', '9999-01-01'),
(10008, 'd005', '1984-07-11', '9999-01-01'),
(10009, 'd006', '1985-02-18', '9999-01-01'),
(10010, 'd006', '1984-08-24', '9999-01-01');
EOF
Verifique se tudo está configurado corretamente:
sudo mysql -u root -p -e "USE employees; SHOW TABLES;"
Agora você configurou ambos os bancos de dados com dados de exemplo e pode acompanhar todos os exemplos deste guia. O banco de dados tecmintdb é perfeito para consultas simples, enquanto o banco de dados employees permite praticar operações mais complexas, como joins e agregações.
Execução Básica de Consulta
Para visualizar todos os bancos de dados no seu servidor, você pode emitir o seguinte comando:
sudo mysql -u root -p -e "show databases;"
Em seguida, para criar uma tabela de banco de dados chamada tutorials no banco de dados tecmintdb, execute o comando abaixo:
sudo mysql -u root -p -e "USE tecmintdb; CREATE TABLE tutorials(tut_id INT NOT NULL AUTO_INCREMENT, tut_title VARCHAR(100) NOT NULL, tut_author VARCHAR(40) NOT NULL, submissoin_date DATE, PRIMARY KEY (tut_id));"
Salvando os Resultados de uma Consulta MySQL em um Arquivo
Usaremos o seguinte comando e encaminharemos a saída para o comando tee, seguido pelo nome do arquivo onde queremos armazenar a saída.
Para ilustração, usaremos um banco de dados chamado employees e um join simples entre as tabelas employees e salaries. No seu caso, basta digitar a consulta SQL entre as aspas e pressionar Enter.
Observe que você será solicitado a inserir a senha do usuário do banco de dados:
sudo mysql -u root -p -e "USE employees; SELECT DISTINCT A.first_name, A.last_name FROM employees A JOIN salaries B ON A.emp_no = B.emp_no WHERE hire_date < '1985-01-31';" | tee queryresults.txt
Visualize os resultados da consulta com a ajuda do comando cat.
cat queryresults.txt
Executar Consultas MySQL/MariaDB pelo Linha de Comando
Com os resultados da consulta em arquivos de texto simples, você pode processar os registros mais facilmente usando outras utilidades de linha de comando. Agora que você viu o básico, vamos explorar algumas técnicas mais avançadas que tornarão seu trabalho com bancos de dados na linha de comando ainda mais eficiente.
Formatando a Saída para Melhor Legibilidade
O formato de tabela padrão é ótimo para visualização no terminal, mas às vezes você precisa de formatos diferentes. Você pode exibir os resultados em formato vertical, o que é particularmente útil ao lidar com tabelas que possuem muitas colunas:
sudo mysql -u root -p -e "USE employees; SELECT * FROM employees LIMIT 1\G"
O \G no final exibe cada linha verticalmente em vez de em uma tabela, então em vez de ver uma tabela horizontal compacta, você obtém algo como:
*************************** 1. row ***************************
emp_no: 10001
birth_date: 1953-09-02
first_name: Georgi
last_name: Facello
gender: M
hire_date: 1984-06-02
Exportando para o formato CSV
Quando você precisa importar resultados de consultas para aplicativos de planilha ou outras ferramentas, o formato CSV é a sua melhor opção:
sudo mysql -u root -p -e "USE employees; SELECT first_name, last_name, hire_date FROM employees WHERE hire_date < '1985-01-31';" | sed 's/\t/,/g' > employees.csv
Isso envia a saída através do sed para substituir tabulações por vírgulas, criando um arquivo CSV adequado que abre corretamente no Excel, LibreOffice Calc ou qualquer outro software de planilhas.
Executando Consultas Sem Solicitação de Senha
Se você está automatizando tarefas de banco de dados com jobs do cron ou scripts, você não vai querer digitar senhas manualmente toda vez; é aí que entram os arquivos de configuração do MySQL.
Crie um arquivo em ~/.my.cnf com suas credenciais:
[client]
user=root
password=your_password_here
Então proteja-o para que apenas você possa lê-lo:
chmod 600 ~/.my.cnf
Agora você pode executar consultas sem a opção -p e sem receber um prompt:
mysql -e "SHOW DATABASES;"
Apenas lembre-se, armazenar senhas em arquivos de texto simples tem implicações de segurança, portanto, use essa abordagem apenas em servidores onde você controla o acesso e considere usar os métodos de autenticação mais seguros do MySQL em ambientes de produção.
Executando Consultas Complexas de Múltiplas Linhas
Às vezes, suas consultas são complexas demais para serem escritas em uma única linha de comando, especialmente quando você está lidando com múltiplos joins, subconsultas ou condições complexas.
Você pode colocar seu SQL em um arquivo e executá-lo:
cat > complex_query.sql << 'EOF'
USE employees;
SELECT
e.first_name,
e.last_name,
d.dept_name,
s.salary
FROM employees e
INNER JOIN dept_emp de ON e.emp_no = de.emp_no
INNER JOIN departments d ON de.dept_no = d.dept_no
INNER JOIN salaries s ON e.emp_no = s.emp_no
WHERE e.hire_date BETWEEN '1985-01-01' AND '1985-12-31'
AND s.from_date = (
SELECT MAX(from_date)
FROM salaries
WHERE emp_no = e.emp_no
)
ORDER BY s.salary DESC
LIMIT 10;
EOF
Agora execute.
sudo mysql -u root -p < complex_query.sql > top_earners_1985.txt
Essa abordagem mantém suas consultas organizadas e reutilizáveis, e você pode controlá-las por versão com o git assim como qualquer outro código.
Processamento em Lote de Múltiplas Consultas
Se você precisar executar várias consultas relacionadas e salvar cada resultado separadamente, você pode escrever um script para isso:
#!/bin/bash
QUERIES=(
"SELECT COUNT(*) as total_employees FROM employees"
"SELECT dept_name, COUNT(*) as employee_count FROM dept_emp de JOIN departments d ON de.dept_no = d.dept_no GROUP BY dept_name"
"SELECT YEAR(hire_date) as year, COUNT(*) as hires FROM employees GROUP BY YEAR(hire_date) ORDER BY year"
)
FILENAMES=(
"total_count.txt"
"dept_distribution.txt"
"yearly_hires.txt"
)
for i in "${!QUERIES[@]}"; do
echo "Running query $((i+1))..."
mysql -u root -p -e "USE employees; ${QUERIES[$i]}" > "${FILENAMES[$i]}"
echo "Results saved to ${FILENAMES[$i]}"
done
Salve isso como um script, torne-o executável com chmod +x e você terá uma ferramenta de consulta em lote reutilizável.
Monitoramento de Consultas de Longa Duração
Quando você está executando consultas que podem levar um tempo, você quer ver o progresso ou pelo menos saber que ainda estão funcionando.
Combine sua consulta com a saída de status:
(sudo mysql -u root -p -e "USE employees; SELECT COUNT(*) FROM large_table WHERE complex_condition;" && echo "Query completed at $(date)") | tee query_log.txt
Para consultas ainda mais longas, execute-as em segundo plano e monitore a lista de processos do MySQL:
sudo mysql -u root -p -e "USE employees; SELECT * FROM massive_table;" > output.txt &
sudo watch -n 5 'mysql -u root -p -e "SHOW PROCESSLIST\G" | grep -A 5 "SELECT"'
Isso executa sua consulta em segundo plano enquanto exibe a lista de processos a cada 5 segundos, para que você possa ver que ela ainda está funcionando e quanto progresso foi feito.
Filtrando e Processando Resultados
Uma vez que você tenha os resultados da consulta em um arquivo de texto, pode usar ferramentas padrão do Linux para processá-los ainda mais. Aqui estão alguns padrões úteis:
Conte o número de linhas de resultado (excluindo o cabeçalho):
tail -n +2 queryresults.txt | wc -l
Extraia colunas específicas usando awk:
awk '{print $1, $3}' queryresults.txt
Procurar por padrões específicos nos resultados:
grep -i "engineering" dept_distribution.txt
Classificar resultados por uma coluna numérica:
tail -n +2 queryresults.txt | sort -k3 -n
Manipulação de Caracteres Especiais e Grandes Conjuntos de Dados
Quando seus dados contêm caracteres especiais, tabulações ou quebras de linha, a saída padrão pode ficar bagunçada, então use as opções --batch e --raw para uma saída mais limpa:
sudo mysql -u root -p --batch --raw -e "SELECT description FROM products WHERE category='electronics';" > products.txt
Para consultas que retornam milhões de linhas, você pode enfrentar problemas de memória; em vez de carregar tudo na memória, faça o streaming dos resultados:
sudo mysql -u root -p --quick -e "SELECT * FROM huge_table;" | gzip > huge_results.txt.gz
A opção --quick diz ao MySQL para recuperar as linhas uma de cada vez em vez de armazenar em buffer todo o conjunto de resultados, e enviar para gzip comprime a saída em tempo real, economizando espaço em disco.
Criando Backups Rápidos de Banco de Dados
Embora isso não seja tecnicamente executar consultas, você pode usar técnicas semelhantes de linha de comando para criar dumps rápidos de banco de dados com o comando mysqldump.
sudo mysqldump -u root -p employees | gzip > employees_backup_$(date +%Y%m%d).sql.gz
Ou faça backup apenas de tabelas específicas:
sudo mysqldump -u root -p employees employees salaries | gzip > critical_tables_$(date +%Y%m%d).sql.gz
Agendamento de Relatórios Automatizados
Combine tudo o que abordamos para criar relatórios diários automatizados usando cron com a ajuda do seguinte script bash.
#!/bin/bash
REPORT_DATE=$(date +%Y-%m-%d)
REPORT_FILE="/var/reports/daily_stats_${REPORT_DATE}.txt"
{
echo "Database Statistics Report - ${REPORT_DATE}"
echo "=========================================="
echo
echo "Total Employees:"
mysql -e "USE employees; SELECT COUNT(*) FROM employees;"
echo
echo "New Hires This Month:"
mysql -e "USE employees; SELECT COUNT(*) FROM employees WHERE MONTH(hire_date) = MONTH(CURRENT_DATE()) AND YEAR(hire_date) = YEAR(CURRENT_DATE());"
echo
echo "Department Distribution:"
mysql -e "USE employees; SELECT d.dept_name, COUNT(*) as count FROM dept_emp de JOIN departments d ON de.dept_no = d.dept_no WHERE de.to_date = '9999-01-01' GROUP BY d.dept_name ORDER BY count DESC;"
} > "$REPORT_FILE"
echo "Report generated: $REPORT_FILE"
Adicione ao cron para executar diariamente às 6h:
0 6 * * * /usr/local/bin/generate_db_report.sh
Resumo
Compartilhamos várias dicas de Linux que você, como administrador de sistemas, pode achar úteis quando se trata de automatizar suas tarefas diárias no Linux ou realizá-las com mais facilidade.
A principal lição aqui é que você nem sempre precisa abrir o shell do MySQL ou usar ferramentas GUI pesadas para trabalhar com seus bancos de dados; a linha de comando oferece velocidade, capacidades de automação e a possibilidade de integrar operações de banco de dados aos seus scripts e fluxos de trabalho existentes.
Você tem alguma outra dica que gostaria de compartilhar com o restante da comunidade? Se sim, por favor, faça isso usando o formulário de comentários abaixo. :

